Как объединить уникальные значения из списка кортежей? - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть 2 списка (из файла Excel), один из которых содержит названия продуктов, а другие содержат номера.

Пример файла Excel:

Example Excel Document

Это означает, что у меня есть 2 списка - разорвано с xlrd.col_values ​​():

products = ['Product1','Product1','Product1','Product2','Product2','Product2']
values = [1,-1,0,2,4,-1]

Конечный результат, который я хотел бы получить, это:

format = [['Product1', [1,-1,0]],['Product2', [2,4,-1]]]

Iпытались сделать это с помощью zip ():

zip_list = list(zip(products, values))

Однако это вернуло:

[('Product1', 1), ('Product1', -1), ('Product1', 0), ('Product2', 2), ('Product2', 4), ('Product2', -1)]

Кто-нибудь знает, как получить желаемый формат?- Я использую python3.

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Вы можете использовать словарь (идеально: collections.defaultdict) для сбора данных, а затем использовать dict.items() для создания вашего формата:

from collections import defaultdict

products = ['Product1','Product1','Product1','Product2','Product2','Product2']
values = [1,-1,0,2,4,-1]

d = defaultdict(list)
# accumulate your data
for prod,val in zip(products,values):
    d[prod].append(val)

print(d)   

# convert dict.items() to your wanted format    
format = [list(i) for i in d.items()] 
print(format)   

Вывод:

defaultdict(<class 'list'>, {'Product1': [1, -1, 0], 'Product2': [2, 4, -1]})

[['Product1', [1, -1, 0]], ['Product2', [2, 4, -1]]]

Использование defaultdict(list) предпочтительнее, чем dict.setdefault(key,[]), или использование try: except:, или тестирование, если key in dict, потому что оно в целом быстрее (встроенная оптимизация), чем любой из других методов.

Доку:


Вы также можете использовать itertools.groupby () , который работает с отсортированными данными (ваши сортируются ), чтобы получить те же результаты:

from itertools import groupby

grped = groupby( zip(products,values), lambda x:x[0]) # group by 1st value

l = []
for g in grped:
    l.append([g[0],list(val for _,val in g[1])])      # extract 2nd value from grouping

print(l) # [['Product1', [1, -1, 0]], ['Product2', [2, 4, -1]]]

Использование groupby в этом списке создает такое же разбиение, посколькуотсортировано - если бы оно не было отсортировано, вы получите другие результаты.

0 голосов
/ 27 декабря 2018

Поскольку понимание словаря не подходит для агрегирования, просто используйте линейный цикл времени:

prods = {}
for item in zip(products, values):
    prod, val = item
    try:
        prods[prod].append(val)
    except KeyError:
        prods[prod] = [val]

# Sample
>>> prods = {}
>>> for item in zip(products, values):
    prod, val = item
    try:
        prods[prod].append(val)
    except KeyError:
        prods[prod] = [val]     
>>> prods
{'Product1': [1, -1, 0], 'Product2': [2, 4, -1]}

Я понимаю, что вы хотели формат [['ProductN', [ ]], но я думаю, что словарь - лучший выбор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...