[string for i, string in enumerate(a)] 在 python 中如何工作?

How does [string for i, string in enumerate(a)] work in python?

提问人:Funnyone 提问时间:8/16/2023 最后编辑:Funnyone 更新时间:8/16/2023 访问量:68

问:

谢谢你帮助我!@juanpa.arrivillaga 在评论中回答了我的问题。我问题的关键点是关于 python 如何知道“我试图将第一个元素分配给 i,将第二个元素分配给字符串”。


我正在学习 python,但工作方式真的让我感到困扰。[string for i, string in enumerate(a)]

这是我在学习 python 时编写的 2 个示例代码

a = ['a','b','c', 'd']
d = [string for string in enumerate(a)]
print (d)

它将返回 '[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]'。但是,如果我编写以下代码

a = ['a','b','c', 'd']

c = [string for i, string in enumerate(a)]
print(c)

它会回来的['a', 'b', 'c', 'd']

在我的理解中,将转换为“枚举对象”,例如RAM内的位置。而且我没有告诉 python i 是什么(我没有告诉 python 是索引或字符串是元素)。因此,代码将被解释为“list[”enumerated object“ iterate inside ”i“]”,但由于我没有告诉python我是什么,所以它会遇到错误。但是,它从 enumerate 返回了一个元素列表。string in enumerate(a)i

python 从哪里从我的代码中学到了枚举中的平均值和索引的均值?stringelementi

python-3.x 列表 枚举

评论

0赞 juanpa.arrivillaga 8/16/2023
“将转换为”枚举对象“,例如RAM内的位置” 我不明白你在这里说什么。除了进程使用易失性内存这一事实之外,这些都与RAM没有直接关系。Python 不知道这意味着字符串,也意味着索引,你告诉它期望两个元素的可迭代,你说 *将第一个元素分配给 ,将第二个元素分配给 。stringiistring
0赞 slothrop 8/16/2023
暂且不谈,你熟悉开箱的工作原理吗?即你是否对此感到满意,并且都是有效的陈述,但结果不同?enumeratea = (3, 4, 5)a, b, c = (3, 4, 5)
0赞 Funnyone 8/16/2023
@Juanpaarrivillaga 那么我在哪里告诉python“将第一个元素分配给i,将第二个元素分配给string”呢?这是我令人困惑的观点。
1赞 juanpa.arrivillaga 8/16/2023
right here: 说:“我希望 ever elemnt in(可迭代对象本身)是一些恰好具有两个元素的可迭代对象。在每次迭代中,将第一项分配给 ,将第二项分配给 。名字无所谓,你可以做到for i, string in whateverwhateveristringfor banana, apple in enumerate(a): print(banana, apple)
1赞 slothrop 8/16/2023
很酷,所以如果你问这个问题“我在哪里告诉 Python 将第一个元素分配给 a,第二个元素分配给 b,第三个元素分配给 c”,这很清楚,对吧?左侧变量的顺序告诉 Python 将哪个元素分配给哪个变量。a, b, c = (3, 4, 5)

答:

1赞 Psytho 8/16/2023 #1

enumerate(a)给你,依此类推。在你的第一个代码中,你的字符串是,这就是你得到的。(0, 'a')(1, 'b')(0, 'a')

在第二个代码中是 (迭代数字 - 0、1 等) 的第一个元素,是第二个元素(即原始列表的元素)。你只在你的列表中,所以你只得到第二个元素,它们是原始列表的元素,这会产生原始列表。i(0, 'a')stringstring


(我没有告诉python是索引或字符串是元素)i

你真的做到了。尝试以下操作并注意其中的区别:

c = [(i, string) for i, string in enumerate(a)]
print(c)
c = [(string, i) for i, string in enumerate(a)]
print(c)

评论

0赞 Funnyone 8/16/2023
仍然有一些困惑,我刚刚在这里读到“for”作为列表推导。所以,'for i: c.append(string)'。我仍然困惑我在哪里告诉 python 'i' = 'index' 和 'string' = 'element'?
0赞 juanpa.arrivillaga 8/16/2023
@Funnyone你不知道,python也不知道。你知道的。python 所知道的只是期待一个大小为 2 的可迭代对象,这正是会给你的。如果你给了它别的东西,例如 您会收到错误。enumerate[for i, x in range(10)]
0赞 Psytho 8/16/2023
@Funnyone将元组的两个元素分配给 和 。第一个元素是索引,第二个元素 ii 是赋值给 的。如何命名变量并不重要!他们的顺序是批判性的。istringistring
0赞 KRG 8/16/2023 #2

因为 enumerate(a) 返回格式为 (index, value_of_index) 的元组的迭代器

第一种情况:'string for string in enumerate(a)',元组(index, value_of_index)存储在变量“string”中,您将其保存在列表“d”中,为您提供元组作为输出。

第二种情况:“i 的字符串,enumerate(a)) 中的字符串”,索引存储在变量 'i' 中,value_of_index存储在 'string' 中,您将 'string' 保存在列表 'c' 中,仅提供列表 'a' 中的值。

评论

1赞 juanpa.arrivillaga 8/16/2023
Enumerate 返回元组的迭代器
1赞 juanpa.arrivillaga 8/16/2023 #3

所以,你需要了解两件事。首先,什么是,其次,可迭代的解包是如何工作的。enumerate

enumerate将可迭代对象作为它的第一个参数和一个关键字参数(如果没有显式传递,则默认为)。它返回一个对的迭代器,即长度为 2 的元组,其中第一个元素是 s 开始并增加 1,第二个元素来自您传递给的原始可迭代对象。start0intstartenumerate

>>> iterable = ["foo", "bar", "baz"]
>>> iterator = enumerate(iterable, start=1)
>>> next(iterator)
(1, 'foo')
>>> next(iterator)
(2, 'bar')
>>> list(iterator)
[(3, 'baz')]

现在,您需要了解赋值目标中的可迭代解包。请注意,在 for 循环或列表推导式(或字典/集合推导式或生成器表达式)的子句中,您正在分配给目标。所以:for

>>> for x in range(4):
...     print(x)
...
0
1
2
3
>>> print("see, x is just a regular variable", x)
see, x is just a regular variable 3

因为,在每次迭代开始时,您都会从子句中的可迭代对象创建的迭代器中获取下一个值。任何进入:in

for <assignment target> in iterable

也可以去:

<assignment target> = whatever

但是,赋值目标可以不仅仅是一个简单的单一变量。最简单的扩展,解压缩为两个变量:

>>> x = 3
>>> x, y = "XY"
>>> x
'X'
>>> y
'Y'
>>> x, y = range(2)
>>> x
0
>>> y
1
>>> x, y = ['foo', 'bar']
>>> x
'foo'
>>> y
'bar'

它可以比这更复杂,但我想你已经明白了。

所以你是在告诉 Pythonfor i, string in whatever

我希望每个元素(本身就是一个可迭代的)都是一些正好有两个元素的可迭代元素。在每次迭代中,将第一项分配给 ,将第二项分配给 。这只是基于位置,名称无关紧要。它们可能是,它的工作方式完全相同。whateveristringfor banana, apple in whatever