【问题标题】:Mysterious for loop in pythonpython中的神秘for循环
【发布时间】:2014-10-23 18:52:34
【问题描述】:

exp = [1,2,3,4,5]

如果我然后执行x in exp,它将给我False。但如果我执行:

for x in exp:
    if x==3:
        print('True')

然后执行x in exp,返回True。这里发生了什么事?我没有给 x 分配任何东西。我有吗?我真的很困惑。

**编辑:**对不起,如果我之前没有这么说:x 之前没有定义。

回答

谢谢大家。我现在明白了。 exp 的元素被分配给 x,因为 exp 被迭代。并且x in exp 等于最后一行代码中的True,因为最后一个元素已分配给x

【问题讨论】:

  • 如果你先执行x in exp,它会给你一个NameError,而不是False
  • 这段代码没有返回任何东西
  • 答案一定是:x 被绑定到一个以前不在exp 中的值。但是,在运行 for 循环之前,您没有告诉我们 x 的状态。
  • 对于那些投票结束的人:这里有一个非常明确的问题(恕我直言)关于循环是否进行分配。我认为这不一定需要关闭。
  • 同意 Amber。这不是一个写得很完美的问题(第二句话中的红鲱鱼肯定没有帮助),但这里有一个真正的问题。除非是 dup,否则我认为没有任何理由关闭它。

标签: python for-loop sequence contains membership


【解决方案1】:

您似乎无意中发现 in 在 Python 中有些过载。

  • x in exp,你在问“x exp吗?”
  • 使用for x in exp: ...,你告诉Python“对于每个元素in exp,调用它x然后做......”

后者会将exp中的每个值一个接一个地分配给x,并使用该值执行循环体,因此在第一次迭代中x被分配1,在第二个2 和最后一个5。另外,x 在循环之后保留这个值!

因此,在循环之前,假设变量x已定义但有一些其他值,x in exp将返回False,而在循环之后,它返回True,因为x仍然是分配来自exp 的最后一个值。

【讨论】:

  • +1,尤其是与定义 in 双重用途的语法的链接。
【解决方案2】:

for x in ... 固有地将值分配给x,因为xa for loop 中的循环变量。

循环的每次迭代都会将一个值分配给x; Python 不会为循环创建新的变量范围。

for x in (1, 2, 3):
    foo(x)

相当于...

x = 1
foo(x)
x = 2
foo(x)
x = 3
foo(x)

【讨论】:

  • 不错的答案。需要说明的一个小问题(OP 甚至无法理解,但可能对通过搜索找到此内容的其他读者有用):列表理解看起来很像 for 循环(因为它是一个循环),但是它确实创建了一个新的变量作用域(但仅在 3.x 中——在 2.x 中,生成器表达式创建新作用域,其他推导不会)。
【解决方案3】:

语法相似,但它们的含义不同。

x in exp是条件表达式;它搜索以查看该值是否 的x 出现在exp 列表中。如果它在那里,则表达式 计算结果为True,否则为False。你也可以使用not in

for x in exp 引入了一个循环,其中x 迭代 exp。循环体将为每个元素调用一次,并且在 正文中,x 将依次设置为每个元素。

【讨论】:

  • "Conditional expression" 在 Python 中的意思是 eggs if spam else beans,而不是 eggs in spam。 (除了“比较表达”之外,后者可能还有一个官方名称,但我并没有想到它。)
  • @abarnert "会员资格测试。"
  • 对不起,我的意思是在条件上下文中使用的表达式,或者其他什么。我总是更擅长使用这些东西,而不是记住它的名字。
【解决方案4】:

这就是循环在 Python 中的工作原理。 'For var in sequence' 将在您遍历序列时分配给 var

例如,如果您只是打印x

for x in [1, 2, 3, 4, 5]:
    print x

您会看到以下内容:

1
2
3
4
5

也许您正在寻找的只是价值的索引?如果是这样,您可以做几件事。

要显式迭代索引,请使用enumerate(sequence)

for index, x in enumerate(mylist):
    if index == 3:
        do_stuff()

第一个值(在这种情况下为index)将始终是当前迭代的索引。

您还可以使用range(len(sequence)) 迭代对象的长度,如果您在迭代时可能会修改列表,这有时会很有用。在这里,您实际上是使用range 创建一个单独的列表,长度等于列表的len。这不会从您的目标列表中分配——而是从range() 创建的列表中分配——因此您必须使用for x in... 作为索引来访问它的列表。

for x in range(len(mylist)):
    if mylist[x] == 3:
        things_and_stuff()

至于您的第二行和混淆点 - 'x in exp' - 您确实会看到 x 在事后仍然分配,因此使用 x in exp 将返回 True 因为最后分配的值x 实际上在 exp 中。

>>> mylist = [1, 2, 3]
>>> for x in mylist:
...     print x
... 
1
2
3
>>> x
3
>>> x in mylist
True

【讨论】:

  • 最后一个比你说的问题更大。在[1, 2, 3, 1, 2, 3] 中,mylist.index(mylist[3]) 不是3,而是0。这是数百个 Stack Overflow 和 python-list 问题的来源……
  • 是的,最后一个很糟糕。我犹豫了一下,如果 OP 没有意识到 for x in sequence 正在以这种方式分配,也许我会完全删除它。
  • 其实是删了
【解决方案5】:

当您运行第一个循环时,变量x 会在您迭代时分配给列表的每个值。

假设您以x=0 开头。

0 不在[1,2,3,4,5],因此x in exp = False

但是,当您运行循环时,您现在有了一个新的x。当循环完成时,x 被初始化为列表中的最后一个元素,即x=5

5 [1,2,3,4,5],因此x in exp = True

【讨论】:

  • 谢谢。我现在知道为什么x in exp = True
猜你喜欢
  • 2014-06-07
  • 1970-01-01
  • 2013-09-16
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多