使用嵌套列表解压缩python的值太多了

Yaf*_*sky 2 python items nested-lists

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
Run Code Online (Sandbox Code Playgroud)

当我传递list_adata_sums它时,它返回[['name1', 4.12]](对于这个特定的情况,它没有任何总和).

当我传递list_bdata_sums它时,它返回一个错误:

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

我试图理解为什么会发生这种情况,但这两个列表的嵌套结构看起来完全相同.

Chr*_*ean 5

你在入境ValueError时得到的原因list_b是因为在做的时候:

for name, value in matrix:
    ...
Run Code Online (Sandbox Code Playgroud)

Python期望some_list能够将元素解压缩为两个变量; namevalue.这是真的list_a.list_a有一个元素可以解压缩到两个变量namevalue.但是,list_b有一个元素具有两个以上的元素.这意味着它无法解压缩为两个变量.因此,提出了例外.

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

>>> 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)]
>>> 
Run Code Online (Sandbox Code Playgroud)

解决此问题的另一种方法是使用列表切片,这种方法的可读性较低且不太通用.

>>> 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)]
>>>  
Run Code Online (Sandbox Code Playgroud)