簡體   English   中英

如何在python中減少元組列表

[英]How to reduce on a list of tuples in python

我有一個數組,我想計算數組中每個項目的出現。

我已經設法使用地圖功能來產生元組列表。

def mapper(a):
    return (a, 1)

r = list(map(lambda a: mapper(a), arr));

//output example: 
//(11817685, 1), (2014036792, 1), (2014047115, 1), (11817685, 1)

我期望reduce函數可以幫助我按每個元組中的第一個數字(id)對計數進行分組。 例如:

(11817685, 2), (2014036792, 1), (2014047115, 1)

我試過了

cnt = reduce(lambda a, b: a + b, r);

和其他一些方法,但是他們都無法解決問題。

注意感謝您提供有關解決問題的其他方法的所有建議,但是我只是在學習Python以及如何在此處實現map-reduce,並且為了使您易於理解,我對我的實際業務問題進行了很多簡化,所以請請向我展示進行map-reduce的正確方法。

您可以使用Counter

from collections import Counter
arr = [11817685, 2014036792, 2014047115, 11817685]
counter = Counter(arr)
print zip(counter.keys(), counter.values())

編輯:

如@ShadowRanger所指出的, Counter具有items()方法:

from collections import Counter
arr = [11817685, 2014036792, 2014047115, 11817685]
print Counter(arr).items()

除了使用任何外部模塊,您還可以使用一些邏輯,而無需任何模塊即可:

track={}
if intr not in track:
    track[intr]=1
else:
    track[intr]+=1

示例代碼:

對於這些類型的列表問題,有一種模式:

因此,假設您有一個列表:

a=[(2006,1),(2007,4),(2008,9),(2006,5)]

並且您想將此轉換為字典,作為元組的第一個元素作為鍵,而將其轉換為元組的第二個元素。 就像是 :

{2008: [9], 2006: [5], 2007: [4]}

但是還有一個陷阱,您還希望那些具有不同值但鍵相同的鍵,例如(2006,1)和(2006,5)鍵相同,但值不同。 您希望這些值僅附加一個鍵,以便預期輸出:

{2008: [9], 2006: [1, 5], 2007: [4]}

對於此類問題,我們執行以下操作:

首先創建一個新的字典,然后遵循以下模式:

if item[0] not in new_dict:
    new_dict[item[0]]=[item[1]]
else:
    new_dict[item[0]].append(item[1])

因此,我們首先檢查key是否在新字典中,如果已經存在,然后將重復key的值添加到其值中:

完整代碼:

a=[(2006,1),(2007,4),(2008,9),(2006,5)]

new_dict={}

for item in a:
    if item[0] not in new_dict:
        new_dict[item[0]]=[item[1]]
    else:
        new_dict[item[0]].append(item[1])

print(new_dict)

輸出:

{2008: [9], 2006: [1, 5], 2007: [4]}

如果只需要cnt ,那么dict可能比這里的tuple list更好(如果需要這種格式,只需使用dict.items )。

為此, collections模塊具有有用的數據結構defaultdict

from collections import defaultdict
cnt = defaultdict(int) # create a default dict where the default value is
                       # the result of calling int
for key in arr:
  cnt[key] += 1 # if key is not in cnt, it will put in the default

# cnt_list = list(cnt.items())

在寫完另一個問題的 答案后,我記得這篇文章,並認為在此處寫一個類似的答案會有所幫助。

這是在列表上使用reduce以獲得所需輸出的一種方法。

arr = [11817685, 2014036792, 2014047115, 11817685]

def mapper(a):
    return (a, 1)

def reducer(x, y):
    if isinstance(x, dict):
        ykey, yval = y
        if ykey not in x:
            x[ykey] = yval
        else:
            x[ykey] += yval
        return x
    else:
        xkey, xval = x
        ykey, yval = y
        a = {xkey: xval}
        if ykey in a:
            a[ykey] += yval
        else:
            a[ykey] = yval
        return a

mapred = reduce(reducer, map(mapper, arr))

print mapred.items()

哪些打印:

[(2014036792, 1), (2014047115, 1), (11817685, 2)]

請參閱鏈接的答案以獲取更詳細的說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM