为什么我可以在 for 循环中使用列表索引作为索引变量? [英] Why can I use a list index as an indexing variable in a for loop?

查看:16
本文介绍了为什么我可以在 for 循环中使用列表索引作为索引变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

a = [0,1,2,3]对于 a[-1] 中的 a:打印(a[-1])

输出为:

<预><代码>0122

我很困惑为什么列表索引可以用作 for 循环中的索引变量.

解决方案

在表达式中列出a[-1]等索引for a[-1] in a> 是有效的 for_stmt(特别是target_list) 语法标记,其中 slicing 是一个有效的赋值目标.

嗯?作业?与我的输出有什么关系?"

确实,它与输出和结果有关.让我们深入了解文档for-in 循环:

<块引用>

for_stmt ::= "for" target_list "in" expression_list ":" suite

表达式列表被评估一次;它应该产生一个可迭代的对象.为 expression_list 的结果创建一个迭代器.然后,按照迭代器返回的顺序,对迭代器提供的每个项目执行一次套件.使用标准分配规则将每个项目依次分配给目标列表(请参阅赋值语句),然后执行套件.

(强调)
注意suite 指的是 for 块下的语句,在我们的特殊情况下,print(a[-1]).

让我们玩得开心并扩展打印语句:

a = [0, 1, 2, 3]对于 a[-1] 中的 a:打印(a, a[-1])

这给出了以下输出:

[0, 1, 2, 0] 0 # a[-1] 赋值为 0[0, 1, 2, 1] 1 # a[-1] 赋值为 1[0, 1, 2, 2] 2 # a[-1] 赋值为2[0, 1, 2, 2] 2 # a[-1] 赋值为2(本身)

(添加评论)

这里,a[-1] 在每次迭代中都会发生变化,我们看到这种变化会传播到 a.同样,这是可能的,因为 slicing 是一个有效的目标.

Ev.Kounis 认为上面引用的文档的第一句话是:表达式列表被评估一次".这是否意味着表达式列表是静态的和不可变的,在 [0, 1, 2, 3] 处保持不变?a[-1] 不应该在最后的迭代中被赋值为 3 吗?

好吧,康拉德·鲁道夫断言:

<块引用>

不,[表达式列表]计算一次以创建一个可迭代对象.但是那个可迭代对象仍然迭代原始数据,而不是它的副本.

(强调)

以下代码演示了一个可迭代的it 懒惰 产生 列表的元素x.

x = [1, 2, 3, 4]它 = iter(x)打印(下一个(它))#1打印(下一个(它))#2打印(下一个(它))#3x[-1] = 0打印(下一个(它))#0

(Kounis')

如果求值是急切的,我们可以期望 x[-1] = 0it 的影响为零,并期望 4打印.这显然不是的情况,并表明根据相同的原理,我们的for循环懒惰地从a 在每次迭代中对 a[-1] 的赋值.

I have the following code:

a = [0,1,2,3]

for a[-1] in a:
  print(a[-1])

The output is:

0
1
2
2

I'm confused about why a list index can be used as an indexing variable in a for loop.

解决方案

List indexes such as a[-1] in the expression for a[-1] in a are valid as specified by the for_stmt (and specifically the target_list) grammar token, where slicing is a valid target for assignment.

"Huh? Assignment? What has that got to do with my output?"

Indeed, it has everything to do with the output and result. Let's dive into the documentation for a for-in loop:

for_stmt ::=  "for" target_list "in" expression_list ":" suite

The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the expression_list. The suite is then executed once for each item provided by the iterator, in the order returned by the iterator. Each item in turn is assigned to the target list using the standard rules for assignments (see Assignment statements), and then the suite is executed.

(emphasis added)
N.B. the suite refers to the statement(s) under the for-block, print(a[-1]) in our particular case.

Let's have a little fun and extend the print statement:

a = [0, 1, 2, 3]
for a[-1] in a:
    print(a, a[-1])

This gives the following output:

[0, 1, 2, 0] 0    # a[-1] assigned 0
[0, 1, 2, 1] 1    # a[-1] assigned 1
[0, 1, 2, 2] 2    # a[-1] assigned 2
[0, 1, 2, 2] 2    # a[-1] assigned 2 (itself)

(comments added)

Here, a[-1] changes on each iteration and we see this change propagated to a. Again, this is possible due to slicing being a valid target.

A good argument made by Ev. Kounis regards the first sentence of the quoted doc above: "The expression list is evaluated once". Does this not imply that the expression list is static and immutable, constant at [0, 1, 2, 3]? Shouldn't a[-1] thus be assigned 3 at the final iteration?

Well, Konrad Rudolph asserts that:

No, [the expression list is] evaluated once to create an iterable object. But that iterable object still iterates over the original data, not a copy of it.

(emphasis added)

The following code demonstrates how an iterable it lazily yields elements of a list x.

x = [1, 2, 3, 4]
it = iter(x)
print(next(it))    # 1
print(next(it))    # 2
print(next(it))    # 3
x[-1] = 0
print(next(it))    # 0

(code inspired by Kounis')

If evaluation was eager, we could expect x[-1] = 0 to have zero effect on it and expect 4 to be printed. This is clearly not the case and goes to show that by the same principle, our for-loop lazily yields numbers from a following assignments to a[-1] on each iteration.

这篇关于为什么我可以在 for 循环中使用列表索引作为索引变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆