值太多,无法用嵌套列表解包python

值太多,无法用嵌套列表解包python,python,nested-lists,items,Python,Nested Lists,Items,当我将列表a传递给数据求和时,它返回[['name1',4.12]](对于这种特定情况,它没有求和) 当我将list_b传递到data_sums时,它返回一个错误: 对于名称,矩阵中的值:ValueError:要解压缩的值太多 我试图理解为什么会发生这种情况,但两个列表的嵌套结构似乎相同。list\u b应该是两个项目列表的列表: list_b=[[name2',2],'name4',4],'name4',1],'name4',6],'name2',6]问题 您需要将列表更改为: list_a

当我将
列表a
传递给
数据求和
时,它返回
[['name1',4.12]]
(对于这种特定情况,它没有求和)

当我将
list_b
传递到
data_sums
时,它返回一个错误:

对于名称,矩阵中的值:ValueError:要解压缩的值太多


我试图理解为什么会发生这种情况,但两个列表的嵌套结构似乎相同。

list\u b
应该是两个项目列表的列表:

list_b=[[name2',2],'name4',4],'name4',1],'name4',6],'name2',6]
问题 您需要将列表更改为:

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
现在:

因为在这个循环中:

>>> data_sums(list_b)
[['name2', 8], ['name4', 11]]
从概念上讲,这种情况会发生:

for name, value in matrix:
name, value = ['name2', 2]
name, value = ['name4', 4]
...
这叫做拆包

对于您的
列表\u b
,会发生以下情况:

for name, value in matrix:
name, value = ['name2', 2]
name, value = ['name4', 4]
...
这会引发此错误:

ValueError:要解压缩的值太多(应为2个)

因为在右边只有一个值,但是Python需要两个值

替代解决方案 您可以从平面列表开始,只需从零和一开始,将第二个元素压缩在一起:

name, value = 'name2'
结果是:

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()]

传入
列表b
时出现
值错误的原因是:

[['name2', 8], ['name4', 11]]
Python希望
some_list
中的元素能够解压为两个变量<代码>名称
。这适用于
列表a
<代码>列表a有一个元素,可以将其解包为两个变量
名称
。但是,
list_b
有一个元素包含两个以上的元素。这意味着它不能被分解成两个变量。因此,提出了例外情况

显而易见的解决方案是将
list_b
重组为一个由元素组成的列表,每个元素都有两个元素。执行此操作的一般方法是使用itertools库中的
grouper
配方:

for name, value in matrix:
    ...
解决此问题的另一种可读性和通用性较差的方法是使用列表切片:

>>> 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)]
>>> 

它不是在做你认为它在做的事情。在第一个列表中,它将两个值拆分为
name
value
。这是因为列表中的项目数量与for循环中的项目数量完全相同

对于第二个列表,有10项,这比您在For循环中解包的两项要多得多

为了使其工作,您的值需要成对嵌套

这将解决您的问题:

>>> 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\u b
仅包含一个元素,
['name2',2',name4',4',name4',1',name4',6',name2',6]
。要在
for
循环中解包
list_b
,需要使用十个变量:

list_b = [['name2', 2], ['name4', 4], [ 'name4', 1], ['name4', 6], ['name2', 6]]
由于以上内容很长且不连贯,您可以展平
list_b
,然后重新组合:

for name1, val, name2, val2, name3, val3, name4, val4, name5, val5 in list_b:
   pass
输出:

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))

列表a
中的每个子列表都有两个元素,您将它们分配给
名称
list_b
的每个子列表都有十个元素,您试图将它们分配给两个标识符。它们完全不同。一个是包含另一个包含两个元素的列表(这就是它成功解压为两个变量的原因),另一个是包含另一个包含10个元素的列表,这就是它无法解压为两个变量的原因。@Patrick Haugh更正。谢谢你指出这一点。我以前在脚本中的其他位置使用了.extend而不是.append,所以现在我将其更改为.append,我使用了
list_b=[[[['name2',2],'name4',4],'name4',1],'name4',6],'name2',6]].
它看起来像一个三重嵌套的列表,而list_a只是两重嵌套的。既然错误仍然存在,这就是问题所在吗?对现在
list_b
的子列表有五个元素(五个长度为2的列表)。您需要使
列表b
的每个子列表都有两个元素。请检查我在帖子上的评论,我已将其修改为正确,但错误仍然存在。@YafimSimanovsky您在
列表b
中仍然只有一个顶级元素。您的真实数据嵌套在三层深处。您需要将
list_b
扁平化为一个由元素组成的列表,每个元素都有两个元素。非常好地使用
zip_b
+1@Ajax1234谢谢我很感激。离金色蟒蛇徽章又近了一步;-)