2017-02-15 23 views
-1

我正在尋找使用python intertools groupby來做一個功能,將小列表分組到一個更大的列表。我開始用不同的數據點具有下列結構(稱爲sortedData)使用itertools groupby排序列表和合並字典

[ 
    [location, date, {item:quantity}], 
    [location2, date, {item2:quantity2}], 
    ... 
] 

我試圖將它們分組,以便每個位置/日期組合與所有的項目和數量字典的列表,以及這些列表按位置分組。這裏有一個例子:

[ 
    [ 
    [Maine, 01062016, {apple:5, orange:2}], 
    [Maine, 02042016,{apple:3, peach:2}] 
    ], 
    [ 
    [Vermont, 01032016, {peach:3}] 
    ] 
] 

什麼我到目前爲止是這樣的代碼,但我無法理解如何使用所創建的組,因爲它不是一個可迭代的項目。現在,它提供了一個空白的列表,但它似乎應該附加的東西

def compileData(sortedData):  
    from itertools import groupby 
    for key, locationGroup in groupby(sortedData, lambda x: x[0]): 
     locationList=[] 
     bigList=[] 
     for date in locationGroup: 
      locationList.append(date) 
     locationList.append(locationGroup) 
     for key, bigList in groupby(locationGroup, lambda x: x[1]): 
      datePlace=[key[0],key[1],{}] 
      for date in locationGroup: 
       datePlace[2]=dict(list(date[2].items())+list(datePlace[2].items())) 
       bigList.append(datePlace) 
     return bigList 

讓我知道你在想什麼,如果你要如何解決這個問題更好的想法,讓我知道。我寫了recursivley,但我使用它的文件太長,所以太慢了。

+0

您可以加入你希望什麼樣的輸出爲請的例子嗎? – miradulo

+0

「使用itertools groupby進行排序」 - 「itertools.groupby」沒有排序。如果你需要對事物進行分類,'itertools.groupby'不會幫助你做到這一點。處理排序後的數據可能會有所幫助,但其他內容需要確保數據已排序。 – user2357112

+0

嗨米奇,第二塊報價有我正在尋找的輸出。 (即列表清單) –

回答

1

我想這你想要做什麼:

from itertools import groupby 
from operator import itemgetter 

def update_with_ignore(a, b): 
    '''Copy only new entries from B to A''' 
    for k,v in b.items(): 
     a.setdefault(k,v) 

def compileData(sortedData): 
    result = [] 
    sortedData = sorted(sortedData, key=itemgetter(0,1)) 
    for location, group in groupby(sortedData, key=itemgetter(0)): 
     l = [] 
     for date, group in groupby(group, key=itemgetter(1)): 
      d = {} 
      for datum in group: 
       update_with_ignore(d, datum[2]) 
      l.append([location, date, dict(d)]) 
     result.append(l) 
    return result 


in_data = [ 
    ["Maine", "01062016", {"apple":5}], 
    ["Maine", "02042016", {"apple":3}], 
    ["Maine", "01062016", {"orange":2}], 
    ["Vermont", "01032016", {"peach":3}], 
    ["Maine", "02042016", {"peach":2}], 
] 
out_data = compileData(in_data) 
assert out_data == [ 
[['Maine', '01062016', {'apple': 5, 'orange': 2}], 
    ['Maine', '02042016', {'apple': 3, 'peach': 2}]], 
[['Vermont', '01032016', {'peach': 3}]]] 

in_data = [ 
    ["Maine", "01062016", {"apple":5}], 
    ["Maine", "01062016", {"apple":4}], 
    ["Maine", "02042016", {"apple":3}], 
] 
out_data = compileData(in_data) 
assert out_data == [ 
[['Maine', '01062016', {'apple': 5}], 
    ['Maine', '02042016', {'apple': 3}]]] 
+0

真的很好。 @Amelia,對於這一切,不會有一個更好的數據結構嗎? – Kelvin

+0

Kelvin,你的意思是有這樣一本字典{(location:date):{item:value}} –

+0

和Rob,非常感謝你。我喜歡列表理解,並且誠實地不熟悉集合,運算符,pprint或assert,所以我將堅持使用第二種解決方案。謝謝! –