2013-08-19 85 views
1

嘿,我已经在下面的Python代码疑问,我写道:Python字典理解迭代器

#create a list of elements 
#use a dictionary to find out the frequency of each element 
list = [1,2,6,3,4,5,1,1,3,2,2,5] 
list.sort() 
dict = {i: list.count(i) for i in list} 
print(dict) 

在字典压缩方法,“因为我在名单”提供给正确的方法的顺序?所以它需要1,2,3,4 ..作为关键。我的问题是为什么不需要三次?因为我已经说过“我在列表中”,是否需要将列表中的每个元素都作为关键字?

(我是新来的Python这样很容易对我!)

+5

顺便说一句,你应该查看'collections.Counter'。 –

回答

5

是的,您的怀疑是正确的。在迭代期间,1将出现3次。但是,由于字典具有唯一键,每次出现1时,它都会用新生成的键/值对替换先前生成的键/值对。这将给出正确的答案,这不是最有效的。您可以在列表转换为一个设置来避免再处理重复键:

dict = {i: list.count(i) for i in set(list)} 

然而,即使这种方法效率极其低下的,因为它全传过来的名单列表中,即O(每个价值N² )总比较。你可以在一个单一的传过来的名单做到这一点,但你不会使用字典理解:

xs = [1,2,6,3,4,5,1,1,3,2,2,5] 
counts = {} 
for x in xs: 
    counts[x] = counts.get(x, 0) + 1 

counts结果是:{1: 3, 2: 3, 3: 2, 4: 1, 5: 2, 6: 1}

编辑:我不知道有在图书馆为你做这件事。您应该使用Rohit Jain的解决方案collections.Counter代替。

+0

感谢您的输入!问题是我的任务需要我用字典来查找频率。所以我不能实现你提供的其他方法。 – Shonu93

7

我的问题是,为什么不要花1个三倍?

这是因为字典键是唯一的。如果为同一个键找到另一个条目,则该键的先前值将被覆盖。

那么,对于您的问题,如果你是只计算在你的列表中的每个元素的频率后,那么你可以使用collections.Counter

请不要使用list变量名。这是一个内置的。

>>> lst = [1,2,6,3,4,5,1,1,3,2,2,5] 
>>> from collections import Counter 
>>> Counter(lst) 
Counter({1: 3, 2: 3, 3: 2, 5: 2, 4: 1, 6: 1}) 
+0

感谢您的输入。请记住它。 – Shonu93