【问题标题】:Understanding "ValueError: need more than 1 value to unpack" w/without enumerate()理解“ValueError:需要超过 1 个值才能解包”,不带 enumerate()
【发布时间】:2015-08-24 20:08:24
【问题描述】:

我一直在寻找关于以下内容“幕后”发生的事情的简洁解释,但到目前为止还没有运气。

为什么,当您尝试以下操作时:

mylist = ["a","b","c","d"]

for index, item in mylist:
    print item

我得到这个错误:

ValueError: need more than 1 value to unpack

但是当我尝试时:

for item in mylist:
    print item

这是返回的:

a
b
c
d

如果索引是列表结构的一部分,为什么我不能将它们与项目一起打印出来?

我知道解决方案是使用enumerate(),但我很好奇为什么遍历列表(不使用enumerate())会以这种方式工作并返回ValueError

我想我不明白的是:如果您可以通过使用它们的索引在列表中找到项目(例如 item = L[index] 的情况) - 这是否意味着某个级别,索引是固有的作为数据结构的列表的一部分?或者item = L[index] 真的只是一种让 Python 使用索引计算列表中项目的方法(显然从 0 开始)?换句话说,item = L[index] 正在将索引“应用”到列表中的项目,从 0 开始。

【问题讨论】:

  • enumerate 返回tuple 的生成器(index, value)。所以你正在解包每个元组。当您尝试解压缩mylist 时,没有索引,它认为您正在尝试将列表的每个元素解压缩到您的两个变量indexitem 中。由于每个项目都是长度为 1 的字符串,因此抱怨您无法将一个字符解压缩为两个变量
  • 如果可行,为什么需要枚举?
  • @Malvin9000,OP 在问为什么我的代码不做与我使用 enumerate 时发生的事情相同的事情,而我不这样做这意味着如果它这样做了,你就不需要 enumerate 这没什么意义
  • @GillBates,是的,你基本上是在问,如果你能做你想做的事,为什么要枚举存在?在任何文档中哪里说索引是列表结构的一部分

标签: python list indexing iteration


【解决方案1】:

如果索引是列表结构的一部分...

除非他们不是。不是当您遍历列表时。索引成为时间/发生的问题,它们不再与元素本身相关联。

【讨论】:

  • 所以我们可以使用item = L[index] 之类的方法通过索引在列表中查找项目,但是当您遍历列表(不使用枚举)时,没有与列表关联的索引?
  • 正确,因为您甚至不能假设您首先正在迭代列表。它可以是任何可迭代的,包括“索引”的概念完全没有意义的那些,例如字典或生成器。
  • @GillBates 不管索引是否是内部列表结构的一部分,列表迭代器都不提供它;它只提供列表元素。
  • @ColonelThirtyTwo 抱歉,在这种情况下,我不清楚您所说的“列表迭代器”是什么意思。
【解决方案2】:

如果您要将enumerate() 函数的结果实际打印为列表:

print(list(enumerate(["a","b","c","d"])))

你会看到这个:

[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

因此,如果您想使用 enumerate() 打印该索引处的索引和项目,从技术上讲,您可以这样写:

for pair in enumerate(mylist):
    print pair[0], pair[1]

但是,这不是最好的( Pythonic)做事方式。 Python 让你可以像这样更好地编写上面的代码:

for index, item in enumerate(mylist):
    print index, item

这是有效的,因为当您使用 index, item 语法时,您是在告诉 Python 通过分别处理每对的组件来“解包”该列表中的每一对。

有关此元组解包魔术如何工作的更多信息,请参阅: Tuple unpacking in for loops

【讨论】:

  • @caelb531 感谢以上内容,我了解枚举的工作原理。我的问题是,当您阅读列表并且人们说所有列表都从索引 [0] 开始时,这对我来说意味着索引以某种方式“内置”到列表的结构中。所以这就是为什么我不明白为什么你不能在不使用枚举的情况下迭代列表中的索引和项目。
  • @GillBates 不要让下标符号 ([0]) 欺骗您。仅仅因为您需要索引来从列表中检索项目并不意味着该索引实际上存储在列表中。索引实际上并不存储在列表对象本身上;那将是非常低效的。相反,Python 以这样一种方式存储列表项,即它知道在给定索引的情况下要检索哪个项目。许多其他编程语言的工作方式类似。
  • @caelb531 好的,所以要明确一点:最后的答案是,列表对象没有内置索引,对吗?而item = L[index] 真的只是一种让 Python 使用索引来计算列表中项目的方法(显然从 0 开始)?换句话说,item = L[index] 正在将索引“应用”到列表中的项目,从 0 开始。
  • 是的,对于列表和元组(它们只是不可变的列表)都是如此。 :)
猜你喜欢
  • 1970-01-01
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多