[英]too many values to unpack python with nested list
list_a = [['name1', 4.12]]
list_b = [['name2', 2, 'name4', 4, 'name4', 1, 'name4', 6, 'name2', 6]]
def data_sums(matrix):
sums = defaultdict(int)
for name, value in matrix:
sums[name] += value
result = [[k,v] for k,v in sums.items()]
return result
当我将list_a
传递给data_sums
,它返回[['name1', 4.12]]
(对于这种特定情况,它没有任何要求和)。
当我将list_b
传递给data_sums
,它返回一个错误:
对于名称,矩阵中的值:ValueError:要解压缩的值太多
我试图理解为什么会发生这种情况,但这两个列表的嵌套结构看起来完全相同。
你在list_b
传递时得到ValueError
的原因是因为在执行时:
for name, value in matrix:
...
Python期望some_list
的元素能够被解压缩为两个变量; name
和value
。 这对list_a
是正确的。 list_a
有一个元素可以解压缩为两个变量name
和value
。 但是, list_b
有一个元素有两个以上的元素。 这意味着它无法解压缩为两个变量。 因此,提出了例外。
显而易见的解决方案是将list_b
重组list_b
每个元素组成的列表,每个元素都有两个元素。 要做到这一点的一般方法是使用grouper
食谱从迭代工具库:
>>> from itertools import zip_longest
>>>
>>> def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
>>> list_b = [['name2', 2, 'name4', 4, 'name4', 1, 'name4', 6, 'name2', 6]]
>>> list_b = list(grouper(list_b[0], 2))
>>> list_b
[('name2', 2), ('name4', 4), ('name4', 1), ('name4', 6), ('name2', 6)]
>>>
解决这个问题的另一种方法是使用列表切片,这种方法的可读性较低且不太通用。
>>> list_b = [['name2', 2, 'name4', 4, 'name4', 1, 'name4', 6, 'name2', 6]]
>>> inner = list_b[0]
>>> list_b = [(a, b) for (a, b) in zip(inner[::2], inner[1::2])]
>>> list_b
[('name2', 2), ('name4', 4), ('name4', 1), ('name4', 6), ('name2', 6)]
>>>
您需要将list_b
更改为:
list_b = [['name2', 2], ['name4', 4], ['name4', 1], ['name4', 6], ['name2', 6]]
现在:
>>> data_sums(list_b)
[['name2', 8], ['name4', 11]]
因为在这个循环中:
for name, value in matrix:
概念上会发生这种情况:
name, value = ['name2', 2]
name, value = ['name4', 4]
...
这称为拆包。
对于list_b
会发生这种情况:
name, value = 'name2'
这引发了这个错误:
ValueError:解压缩的值太多(预期2)
因为右边只有一个值,但Python需要两个。
你可以从平面列表开始,然后通过开始零和一个将每个第二个元素压缩在一起:
flat_list = ['name2', 2, 'name4', 4, 'name4', 1, 'name4', 6, 'name2', 6]
sums = defaultdict(int)
for name, value in zip(flat_list[::2], flat_list[1::2]):
sums[name] += value
result = [[k,v] for k,v in sums.items()]
结果是:
[['name2', 8], ['name4', 11]]
list_b
应该是2个项目列表的列表:
list_b = [['name2', 2], ['name4', 4], ['name4', 1], ['name4', 6], ['name2', 6]]
它没有做你认为它正在做的事情。 在第一个列表中,它将两个值分成name
和value
。 这是有效的,因为列表中的项目数量与for循环中的项目数量完全相同。
对于第二个列表,有10个项目,这比在for循环中解压缩的两个项目更多。
为了实现这一点,您的值需要以两对的形式嵌套。
这可以解决您的问题:
list_b = [['name2', 2], ['name4', 4], [ 'name4', 1], ['name4', 6], ['name2', 6]]
list_b
只包含一个元素, ['name2', 2, 'name4', 4, 'name4', 1, 'name4', 6, 'name2', 6]
。 要在for
循环中解压缩list_b
,您需要使用十个变量:
for name1, val, name2, val2, name3, val3, name4, val4, name5, val5 in list_b:
pass
由于上面很长且是unpythonic,你可以展平list_b
然后重新组合:
from collections import defaultdict
def data_sums(matrix):
sums = defaultdict(int)
for name, value in matrix:
sums[name] += value
result = [[k,v] for k,v in sums.items()]
return result
list_b = [['name2', 2, 'name4', 4, 'name4', 1, 'name4', 6, 'name2', 6]]
list_b = [i for b in list_b for i in b]
final_b = [list_b[i:i+2] for i in range(0, len(list_b), 2)]
print(data_sums(final_b))
输出:
[['name4', 11], ['name2', 8]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.