2015-07-03 52 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