2015-07-03 58 views
4

我有一个元组列表,例如a = [(1,2),(1,4),(1,2),(6,7),(2,9)],我想检查每个元组的元素之一是否有重复次数和次数。 例如,检查只有列表的所有元组的第一部分是否有dublicate并返回元组,并且发布了多少次。 我可以做到这一点下面的代码:计算元组列表中的重复项

a = [(1,2), (1,4), (1,2), (6,7), (2,9)] 

coll_list = [] 
for t in a: 
    coll_cnt = 0 
    for b in a: 
     if b[0] == t[0]: 
      coll_cnt = coll_cnt + 1 
    print "%s,%d" %(t,coll_cnt) 
    coll_list.append((t,coll_cnt)) 

print coll_list 

我想知道是否有做这样的事情更有效的方式?

+0

'collections.Counter(a)'会给你计数。 – jonrsharpe

+2

如果你的代码正在工作,但你想改善它,你可以在这里发布它:codereview.stackexchange.com – DJanssens

+0

你可能想要显示预期的输出,因为下面的很多答案似乎是关于找到重复的元组,而不是元组中的重复值。 – Rick

回答

6

使用集合库。在下面的代码val_1中,val_2分别给出了元组的第一个元素和第二个元素的重复项。

import collections 
val_1=collections.Counter([x for (x,y) in a]) 
val_2=collections.Counter([y for (x,y) in a]) 

>>> print val_1 
<<< Counter({1: 3, 2: 1, 6: 1}) 

这是每个元组

>>> print val_2 
<<< Counter({2: 2, 9: 1, 4: 1, 7: 1}) 

此的第一个元素的出现次数被每个元组

3

您可以制作count_map,并将每个元组的计数存储为该值。

>>> count_map = {} 
>>> for t in a: 
...  count_map[t] = count_map.get(t, 0) +1 
... 
>>> count_map 
{(1, 2): 2, (6, 7): 1, (2, 9): 1, (1, 4): 1} 
+0

你也可以使用'collections.defaultdict(int)'来避免'get'的尴尬。 – jonrsharpe

+1

OP不希望每个元组出现的次数。 – doru

+0

@doru OP的代码说不然。他/她已经逐一计算了所有元组的计数,使其成为N^2操作。 – Sudipta

10

您可以使用Counter

from collections import Counter 
a = [(1,2),(1,4),(1,2),(6,7),(2,9)] 
counter=Counter(a) 
print counter 

这将输出:

Counter({(1, 2): 2, (6, 7): 1, (2, 9): 1, (1, 4): 1}) 

好像是与项目对象字典(在这种情况下,元组)作为密钥和包含密钥被查看次数的值。您的(1,2)元组被看到两次,而其他所有元素只被看到一次。

>>> counter[(1,2)] 
2 

如果感兴趣的元组的每个单独的部分,则可以利用相同的逻辑,用于在所述元组的每个元素。

first_element = Counter([x for (x,y) in a]) 
second_element = Counter([y for (x,y) in a]) 

first_elementsecond_element现在包含时间值的数量的Counter元组被认为每个元素

>>> first_element 
Counter({1: 3, 2: 1, 6: 1}) 
>>> second_element 
Counter({2: 2, 9: 1, 4: 1, 7: 1}) 

同样,这些字典喜欢的对象,所以你可以检查如何频繁具体值直接出现:

>>> first_element[2] 
1 

在第一个元素t的元组列表中,值为2出现了1次。

+1

OP不希望每个元组出现的次数。 – doru

2

使用熊猫的第二元件的出现的次数,这是简单和非常快:

import pandas 
print(pandas.Series(data=[(1,2),(1,4),(1,2),(6,7),(2,9)]).value_counts()) 

(1, 2) 2 
(1, 4) 1 
(6, 7) 1 
(2, 9) 1 
dtype: int64 
+1

OP不希望每个元组出现的次数。 – doru

2

也许词典可以更好地工作。因为在你的代码中,你正在旅行两次。这使得你的代码O(n^2)的complexity。这不是一件好事:)

最好的方法是一次旅行,并为每次遍历使用1或2个条件。这是我解决这类问题的第一个解决方案。

a = [(1,2),(1,4),(1,2),(6,7),(2,9)] 

dict = {} 
for (i,j) in a: 
    if dict.has_key(i): 
      dict[i] += 1 
    else: 
      dict[i] = 1 

print dict 

对于此代码,这会给输出:

{1: 3, 2: 1, 6: 1} 

我希望这将是有益的。

+0

你可以使用'collections.defaultdict(int)'来清理循环内部 – Rick

+0

是的,那就清楚了。但是如果我使用集合,为什么要尝试循环,对吧? :)我更喜欢像安迪的解决方案;) – cengineer