Старайтесь избегать сложных вложенных структур данных. Я считаю, что люди склонны
Грок их только тогда, когда они интенсивно используют структуру данных. После
программа завершена или отложена на некоторое время, структура данных быстро
становится загадочным.
Объекты могут использоваться для сохранения или даже добавления богатства к структуре данных более рациональным и организованным способом. Например, кажется, item
и price
всегда идут вместе. Таким образом, две части данных могут также быть объединены в объекте:
class Item(object):
def __init__(self,name,price):
self.name=name
self.price=price
Точно так же у человека, похоже, есть id
и name
и набор вещей:
class Person(object):
def __init__(self,id,name,*items):
self.id=id
self.name=name
self.items=set(items)
Если вы купитесь на идею использования таких классов, то ваш list_dicts
может стать
list_people = [
Person('001','jim',Item('pencil',0.99)),
Person('002','mary',Item('book',15.49)),
Person('002','mary',Item('tape',7.99)),
Person('003','john',Item('pen',3.49)),
Person('003','john',Item('stapler',9.49)),
Person('003','john',Item('scissors',12.99)),
]
Затем, чтобы объединить людей на основе id
, вы можете использовать функцию reduce
Python,
вместе с take_items
, который берет (объединяет) предметы от одного человека и передает их другому:
def take_items(person,other):
'''
person takes other's items.
Note however, that although person may be altered, other remains the same --
other does not lose its items.
'''
person.items.update(other.items)
return person
Собираем все вместе:
import itertools
import operator
class Item(object):
def __init__(self,name,price):
self.name=name
self.price=price
def __str__(self):
return '{0} {1}'.format(self.name,self.price)
class Person(object):
def __init__(self,id,name,*items):
self.id=id
self.name=name
self.items=set(items)
def __str__(self):
return '{0} {1}: {2}'.format(self.id,self.name,map(str,self.items))
list_people = [
Person('001','jim',Item('pencil',0.99)),
Person('002','mary',Item('book',15.49)),
Person('002','mary',Item('tape',7.99)),
Person('003','john',Item('pen',3.49)),
Person('003','john',Item('stapler',9.49)),
Person('003','john',Item('scissors',12.99)),
]
def take_items(person,other):
'''
person takes other's items.
Note however, that although person may be altered, other remains the same --
other does not lose its items.
'''
person.items.update(other.items)
return person
list_people2 = [reduce(take_items,g)
for k,g in itertools.groupby(list_people, lambda person: person.id)]
for person in list_people2:
print(person)