您是否可以列出不等长度的列表并将其写入一系列列,同时匹配另一个列表的顺序?
order = ['bx', 'cs', 'lb', 'pc']
totals = [
[{'unit': 'pc', 'sum': Decimal('3.00')}],
[{'unit': 'bx', 'sum': Decimal('3.00')}, {'unit': 'pc', 'sum': Decimal('16.00')}],
[{'unit': 'bx', 'sum': Decimal('6.00')}, {'unit': 'lb', 'sum': Decimal('24.00')}, {'unit': 'pc', 'sum': Decimal('63.00')}],
[{'unit': 'pc', 'sum': Decimal('36.00')}],
[{'unit': 'bx', 'sum': Decimal('31.00')}]
]
desired_format = [
['', '', '', '3.00 pc'],
['3.00 bx', '', '', '16.00 pc'],
['6.00 bx', '', '24.00 lb', '63:00 pc'],
['', '', '', '36:00 pc'],
['31.00 bx', '', '', ''],
]
我已尝试过以下但如果按顺序排列所有4个单位,则无法正常工作。
desired_format = [[]]
for total in totals:
data = []
for idx, um in enumerate(total):
if um['unit'] == order[idx]:
data.append(str(um['sum'] + ' ' + str(um['unit'])))
else:
data.append('')
desired_format.append(data)
我也试过这个,最后会出现太多空列和不均匀/无序列
desired_format = [[]]
for total in totals:
data = []
for um in total:
for unit in order:
if um['unit'] == unit:
data.append(str(um['sum'] + ' ' + str(um['unit'])))
else:
data.append('')
desired_format.append(data)
答案 0 :(得分:0)
这不是最有效的方法
converters = [{dict['unit']: dict['sum'] for dict in total} for total in totals]
desired_format = [[str(converter[item])+' '+item if item in converter else '' for item in order] for converter in converters]
这个想法是你的总数是一个词典列表的列表。转换器使用列表推导将其转换为字典列表
然后你可以对其中一个词典进行列表理解,以便通过它迭代顺序:如果项目按顺序存在,则给出所需的输出,否则给出''
可能有一种方法可以在不首先生成转换器的情况下执行此操作,这可能会使代码更快。
答案 1 :(得分:0)
我建议您根据原始帖子提供以下代码:
desired_format = []
for total in totals:
data = []
for orderValue in order:
found = False
for um in total:
if um['unit'] == orderValue:
found = True
break
if found:
data.append(str(um['sum'] + ' ' + str(um['unit'])))
else:
data.append('')
desired_format.append(data)
print(desired_format)
答案 2 :(得分:0)
你的尝试非常接近,但包含了一些问题(忽略了关闭一些括号)。
首先,您初始化列表为desiredFormat = [[]]
,即创建列表,然后将第一个元素设为空列表。相反,您只需要使用[]
创建空列表,然后将后续列表推送到该列表。
此外,在循环列表时,为每个部分创建新的列表元素,而不是在第二个对象存在时重写。
试试这个:
desired_format = []
for total in totals:
data = [''] * len(order)
for um in total:
for i, unit in enumerate(order):
if um['unit'] == unit:
data[i] = str(um['sum']) + ' ' + str(um['unit'])
desired_format.append(data)
首先创建空列表,然后在列表循环时使用额外信息更新它。
答案 3 :(得分:0)
以下是collections.defaultdict
的一个解决方案:
from collections import defaultdict
d = defaultdict(list)
for idx, i in enumerate(totals):
for j in order:
d_item = next((str(k['sum']) + ' ' + j for k in i if k['unit'] == j), '')
d[idx].append(d_item)
res = [d[i] for i in range(len(totals))]
# [['', '', '', '3.00 pc'],
# ['3.00 bx', '', '', '16.00 pc'],
# ['6.00 bx', '', '24.00 lb', '63.00 pc'],
# ['', '', '', '36.00 pc'],
# ['31.00 bx', '', '', '']]
答案 4 :(得分:0)
以下解决方案依赖于创建最初使用默认值len(order)
填充的维度len(totals)
x ''
的表格。然后,我们根据totals
中的已知值填充表格,其余为''
。
# Have your order as dict for quick lookup
order_keys = dict(map(reversed, enumerate(order)))
# This output the indexing: {'bx': 0, 'cs': 1, 'lb': 2, 'pc': 3}
# Create the empty table for the desired output, default value will be ''
output = [[''] * len(order_keys) for _ in range(len(totals))]
# output:
# [['', '', '', ''],
# ['', '', '', ''],
# ['', '', '', ''],
# ['', '', '', ''],
# ['', '', '', '']]
for index, row in enumerate(totals):
for col in row:
unit = col['unit']
output[index][order_keys[unit]] = '{} {}'.format(col['sum'], col['unit'])
# output:
# [['', '', '', '3.00 pc'],
# ['3.00 bx', '', '', '16.00 pc'],
# ['6.00 bx', '', '24.00 lb', '63.00 pc'],
# ['', '', '', '36.00 pc'],
# ['31.00 bx', '', '', '']]