2017-02-15 15 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 для сортировки» - '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

Келвин, вы имеете в виду наличие такого словаря {(location: date): {item: value}} –

+0

И Роб, большое вам спасибо. Мне нравится понимание списков, и, честно говоря, я не знаком с коллекциями, оператором, pprint или assert, поэтому я буду придерживаться вашего второго решения. Благодаря! –