我有2个列表(来自excel文件),其中一个包含产品名称,另一个包含数字。
Excel文件示例:
这意味着我有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]]]
我尝试使用zip()进行此操作:
zip_list = list(zip(products, values))
但是这返回了:
[('Product1', 1), ('Product1', -1), ('Product1', 0), ('Product2', 2), ('Product2', 4), ('Product2', -1)]
有人会知道如何获得所需的格式吗? -我正在使用python3。
答案 0 :(得分:2)
您可以使用字典(理想情况: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
更为可取,因为它的整体速度(内置优化)比其他任何方法都要快。
Doku:
您还可以利用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
会创建相同的分区,因为该分区已排序-如果未排序,则会得到不同的结果。
答案 1 :(得分:1)
由于字典理解不适合聚合,因此请使用线性时间循环:
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', [ ]]
格式,但是我认为字典是更好的选择。