如何在dict中添加索引

L t*_*e V 4 python indexing dictionary list-comprehension list

例如,给定:

['A', 'B', 'A', 'B']    
Run Code Online (Sandbox Code Playgroud)

我希望有:

{'A': [0, 2], 'B': [1, 3]}
Run Code Online (Sandbox Code Playgroud)

我尝试了一个类似的循环; 添加找到字符的位置的索引,然后替换它,''以便下次循环通过时,它会传递给下一个字符.

但是,由于其他原因,这个循环不起作用,我不知道如何继续.

wil*_*lnx 9

使用enumeratesetdefault:

example = ['a', 'b', 'a', 'b']
mydict = {}
for idx, item in enumerate(example):
     indexes = mydict.setdefault(item, [])
     indexes.append(idx)
Run Code Online (Sandbox Code Playgroud)

  • 你也可以`from collections import defaultdict`并使用`mydict = defaultdict(list)`,然后你不需要运行`mydict.setdefault(item,[ ])"你自己,我认为它会更像Pythonic. (4认同)

Aks*_*jan 5

一个简单的字典理解应该可以解决问题:

{key: [index for index, x in enumerate(my_list) if x == key] for key in my_list}
Run Code Online (Sandbox Code Playgroud)

一个简单的试验:

>>>> my_list = ['A','B','A','B']
>>>> {key: [index for index, x in enumerate(my_list) if x == key] for key in my_list}
>>>> {'A': [0, 2], 'B': [1, 3]}
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

列表推导式通常在 Python 中用作 for 循环的语法糖。而不是写作

my_list = []
for item in range(10):
    my_list.append(item)
Run Code Online (Sandbox Code Playgroud)

列表推导式本质上让您将这一系列语句浓缩为一行:

my_list = [item for item in range(10)]
Run Code Online (Sandbox Code Playgroud)

每当您看到列表推导式时,您应该记住它只是原始三行语句的精简版本。它们实际上是相同的——这里提供的唯一好处是简洁。

一个类似的相关物种是词典理解。这是一个类似的列表理解,不同的是它允许你指定两个在同一时间的键和值。

字典理解的一个例子:

{k: None for k in ["Hello", "Adele"]}
>>>> {"Hello": None, "Adele": None}
Run Code Online (Sandbox Code Playgroud)

在我提供的答案中,我只是使用了字典理解

  • 翻出key从smy_list
  • 为每个keyfrom分配一个索引列表my_list作为相应的值

从语法上讲,它扩展为一个相当复杂的程序,如下所示:

my_dict = {}
for key in my_list:
    indices = []
    for index,value in enumerate(my_list):
         if value == key:
              indices.append(index)
    my_dict[key] = indices
Run Code Online (Sandbox Code Playgroud)

enumerate是一个标准库函数,它返回一个元组列表。每个元组的第一个元素引用列表的索引,第二个元素引用列表中该索引处的值。

观察:

 enumerate(['a','b','a','b'])
 >>>> [(0,'a'),(1,'b'),(2,'b'),(3,'b')]
Run Code Online (Sandbox Code Playgroud)

那就是 的力量enumerate

效率

与往常一样,过早优化是万恶之源。这种实现确实是低效的:它重复工作,并以二次时间运行。最重要的事情,但是,是要问,如果它是对你有特殊的任务。对于相对较小的列表,这已经足够了。

您可以查看某些优化。@wilinx 的方式很有效。评论中的@Rob 建议迭代set(my_list),以防止重复工作。