【问题标题】:ValueError on list when using for loop使用 for 循环时列表上的 ValueError
【发布时间】:2020-01-18 13:13:58
【问题描述】:

我在使用 for 循环处理列表列表时遇到问题,该循环将列表元素分配给变量,而不是使用列表索引。

以下代码正确处理列表,并确认每个子列表有 5 个元素,所有元素均为字符串类型且均包含数据:

for i, rec in enumerate(Wordpress_Post_List): 
    if i < 5:
        if i == 0:
            print(type(rec), ' -->  ', len(rec))
        print('record ',i)
        print('0==', type(rec[0]), '==', rec[0])
        print('1==', type(rec[1]), '==', rec[1])
        print('2==', type(rec[2]), '==', rec[2])
        print('3==', type(rec[3]), '==', rec[3])
        print('4==', type(rec[4]), '==', rec[4])

但是当我使用以下代码时:

for i, rec in enumerate(Wordpress_Post_List): 
    if i < 5:
        for li0,li1,li2,li3,li4 in rec:
            print('0==', type(li0), '==', li0)
            print('1==', type(li1), '==', li1)
            print('2==', type(li2), '==', li2)
            print('3==', type(li3), '==', li3)
            print('4==', type(li4), '==', li4)

我收到错误:ValueError: not enough values to unpack (expected 5, got 2)

任何关于 Python 为何这样做的见解将不胜感激。

PS。下面的代码也可以。

for i, rec in enumerate(Wordpress_Post_List): 
    if i < 5:
        li0=rec[0]
        li1=rec[1]
        li2=rec[2]
        li3=rec[3]
        li4=rec[4]
        print('0==', type(li0), '==', li0)
        print('1==', type(li1), '==', li1)
        print('2==', type(li2), '==', li2)
        print('3==', type(li3), '==', li3)
        print('4==', type(li4), '==', li4)

【问题讨论】:

  • 请在您的问题中包含在Wordpress_Post_List 中找到的值类型的示例以及预期输出。
  • 在这种特定情况下,我们可以对出了什么问题做出有根据的猜测,但是有一个很好的例子来说明嵌套结构会让我们变得很多,much 更有效。而不仅仅是显示异常,通常还需要完整的回溯,因此我们不仅可以查看引发了什么异常,还可以查看 Python 是如何到达那里的,以及问题发生在哪一行确切

标签: python python-3.x list valueerror


【解决方案1】:

您正在对rec 进行迭代,因此rec 中的每个单个值 都分配给了5 个变量。这些值中至少有一个本身就是一个序列(可能是一个字符串),并且只有 2 个元素长,并且 2 个元素不能分配给 5 个变量。

例如如果Wordpress_Post_List 中的第一个条目是 5 个字符串的列表:

['on', 'a', 'distant', 'hazy', 'hill']

然后for 循环采用'on' 并将其分配给for 循环目标。您将目标设置为li0,li1,li2,li3,li4,并且因为字符串也是序列,Python 尝试将字符'o''n' 分配给5 个变量名。那行不通,所以你得到你的特定例外:

>>> rec = ['on', 'a', 'distant', 'hazy', 'hill']
>>> for li0,li1,li2,li3,li4 in rec:
...     pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 5, got 2)

不要使用另一个 for 循环,只需对这 5 个名称使用 分配

if i < 5:
    li0, li1, li2, li3, li4 = rec

您可以使用itertools.islice() function 对象将迭代限制在前5 行,而不是使用enumerate() 和针对i 的测试。因为您知道前五个条目都正好有 5 个元素,所以您可以在外循环中使用解包:

from itertools import islice

for li0, li1, li2, li3, li4 in islice(Wordpress_Post_List, 5):
    print('0==', type(li0), '==', li0)
    print('1==', type(li1), '==', li1)
    print('2==', type(li2), '==', li2)
    print('3==', type(li3), '==', li3)
    print('4==', type(li4), '==', li4)

【讨论】:

  • 我相信我在这里感到困惑的原因是,当主列表包含多个子列表时,“主列表中的 a、b、c”代码可以正常工作,但我发现如果主列表只有其中有 1 个子列表。
  • 感谢 Martijn 的帮助和解释。
  • 很高兴能帮上忙!如果您觉得它对您有用,请随时 accept my answer。 :-)
【解决方案2】:

您的代码正在尝试解压缩每个迭代

for (unpack,my,data,structure) in iterable_of_data_structures:

for li0,li1,li2,li3,li4 in rec:

这要求rec的每次迭代有5个值;但是,我们可以从您之前的代码中看到,rec 总共有 5 个值

您无需迭代即可解压: (li0, li1, li2, li3, li4) = rec

【讨论】:

  • 不太对。 rec 包含 5 个值;如果您迭代 rec,您将迭代这 5 个值,然后尝试使用您的 for li0,li1,li2,li3,li4 in rec: 行将迭代器当前所在的值解压缩为 5 个变量。
  • 将代码“for i, rec in enumerate(Wordpress_Post_List):”替换为代码“for i, (li0,li1,li2,li3,li4) in enumerate(Wordpress_Post_List):”确实有效.我的印象是我可以使用 for 语句将列表中的每个元素放入自己的变量中,从而避免使用索引。仍然不明白为什么一种形式有效而另一种失败。
  • 您要执行两个操作:迭代操作和解包操作。您只想迭代Wordpress_Post_list 结构,并且只想解压rec 结构。当您执行for i, (li0,li1,li2,li3,li4) in enumerate(Wordpress_Post_List): 时,您在一个语句中进行迭代和解包,一切都很好。当您执行for i, rec in enumerate(Wordpress_Post_List): 时,您会进行迭代,然后您可以使用(li0, li1, li2, li3, li4) = rec 之类的内容解压缩,一切都很好。您的问题代码尝试迭代、迭代和解包:迭代次数过多。
猜你喜欢
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多