簡體   English   中英

困惑於itertools groupby求和

[英]Baffled by itertools groupby summation

考慮一下...

from itertools import groupby
from operator import itemgetter

data = [{'pid': 1, 'items': 1}, {'pid': 2, 'items': 5}, {'pid': 1, 'items': 3}]
data = sorted(data, key=itemgetter('pid'))

for pid, rows in groupby(data, lambda x: x['pid']):
    print(pid, sum(r['items'] for r in rows))
    for key in ['items']:
        print(pid, sum(r[key] for r in rows))

第一個print()調用將為pid 1打印正確的#,4,為2 print() 5,第二個print()調用在通過鍵列表進行循環中的打印為0。 這是怎么回事?

groupby獲得的rows對象是一種只能使用一次的生成器。 當您遍歷第一個print語句時,您將消耗這些值,因此,當您下次嘗試對其進行遍歷時, rows是一個空生成器-您已經訪問並用盡了對其迭代功能的訪問權限。

您可以使用row_list = list(rows)然后使用row_list使項目在多個迭代遍歷中保持row_list

為了更加清晰,我建議將您的代碼放入Python REPL中,並在該循環中檢查type(rows) ,並查看該對象提供的API。

生成器遇到了一個非常普遍的問題-生成器只能迭代一次。 itertools通常會返回生成器。

groupby文檔中

返回的組本身就是一個迭代器,它與groupby()共享基礎的可迭代對象。 因為源是共享的,所以當前進groupby()對象時,先前的組不再可見。

只需刪除您的print()調用之一,並觀察其工作即可。 如果您需要多次訪問返回的數據,則列表是保存結果的潛在結構。

固定代碼:

from itertools import groupby
from operator import itemgetter

data = [{'pid': 1, 'items': 1}, {'pid': 2, 'items': 5}, {'pid': 1, 'items': 3}]
data = sorted(data, key=itemgetter('pid'))

for pid, rows_gen in groupby(data, lambda x: x['pid']):
    rows=list(rows_gen)      # save the group to access more than once
    print(pid, sum(r['items'] for r in rows))
    for key in ['items']:
        print(pid, sum(r[key] for r in rows))

暫無
暫無

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

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