for y in y():这是如何工作的? [重复]

时间:2022-02-28 23:31:35

This question already has an answer here:

这个问题在这里已有答案:

I was looking for code to spin a cursor in the terminal and found this. I was wondering what was happening in the code. In particular for c in spinning_cursor(): I've never seen this syntax. Is it because I am returning one element from a generator at a time with yield, and this is assigned to c? Any other examples of this for x in y() use?

我正在寻找代码来在终端中旋转光标并找到它。我想知道代码中发生了什么。特别是对于spinning_cursor()中的c:我从未见过这种语法。是因为我一次从yield中返回一个生成元素,并将其赋值给c?在y()中使用x的任何其他例子?

import sys
import time

def spinning_cursor():
    cursor='/-\|'
    i = 0
    while 1:
        yield cursor[i]
        i = (i + 1) % len(cursor)

for c in spinning_cursor():
    sys.stdout.write(c)
    sys.stdout.flush()
    time.sleep(0.1)
    sys.stdout.write('\b')

5 个解决方案

#1


41  

Using yield turns a function into a generator. A generator is a specialized type of iterator. for always loops over iterables, taking each element in turn and assigning it to the name(s) you listed.

使用yield将函数转换为生成器。生成器是一种特殊类型的迭代器。 for always循环遍历iterables,依次获取每个元素并将其分配给您列出的名称。

spinning_cursor() returns a generator, the code inside spinning_cursor() doesn't actually run until you start iterating over the generator. Iterating over a generator means the code in the function is executed until it comes across a yield statement, at which point the result of the expression there is returned as the next value and execution is paused again.

spinning_cursor()返回一个生成器,在您开始迭代生成器之前,spinning_cursor()中的代码实际上不会运行。迭代生成器意味着函数中的代码将被执行,直到遇到yield语句,此时表达式的结果将作为下一个值返回并再次暂停执行。

The for loop does just that, it'll call the equivalent of next() on the generator, until the generator signals it is done by raising StopIteration (which happens when the function returns). Each return value of next() is assigned, in turn, to c.

for循环就是这样,它将在生成器上调用next()的等价物,直到生成器通过提高StopIteration(在函数返回时发生)来发出信号。 next()的每个返回值依次分配给c。

You can see this by creating the generator on in the Python prompt:

您可以通过在Python提示符中创建生成器来查看:

>>> def spinning_cursor():
...     cursor='/-\|'
...     i = 0
...     while 1:
...         yield cursor[i]
...         i = (i + 1) % len(cursor)
... 
>>> sc = spinning_cursor()
>>> sc
<generator object spinning_cursor at 0x107a55eb0>
>>> next(sc)
'/'
>>> next(sc)
'-'
>>> next(sc)
'\\'
>>> next(sc)
'|'

This specific generator never returns, so StopIteration is never raised and the for loop will go on forever unless you kill the script.

这个特定的生成器永远不会返回,因此永远不会引发StopIteration,并且for循环将永远继续,除非您终止该脚本。

#2


4  

In Python, the for statement lets you iterate over elements.

在Python中,for语句允许您迭代元素。

According the documentation :

根据文件:

Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence

Python的for语句按照它们出现在序列中的顺序迭代任何序列(列表或字符串)的项目

Here, the element will be the return value of spinning_cursor().

这里,元素将是spinning_cursor()的返回值。

#3


3  

The for c in spinning_cursor() syntax is a for-each loop. It's going to iterate through each item in the iterator returned by spinning_cursor().

spinning_cursor()语法中的for c是for-each循环。它将遍历spinning_cursor()返回的迭代器中的每个项目。

The inside of the loop will:

循环内部将:

  1. Write the character to standard out and flush so it displays.
  2. 将字符写入标准输出并刷新以显示。
  3. Sleep for a tenth of a second
  4. 睡了十分之一秒
  5. Write \b, which is interpreted as a backspace (deletes the last character). Notice this happens at the end of the loop so it won't be written during the first iteration, and that it shares the flush call in step 1.
  6. 写\ b,它被解释为退格(删除最后一个字符)。请注意,这发生在循环结束时,因此在第一次迭代期间不会写入,并且它在步骤1*享刷新调用。

spinning_cursor() is going to return a generator, which doesn't actually run until you start iterating. It looks like it will loop through '/-\|', in order, forever. It's kind of like having an infinite list to iterate through.

spinning_cursor()将返回一个生成器,在您开始迭代之前,它不会实际运行。看起来它会永远循环遍历'/ - \ |'。这有点像有一个无限的列表来迭代。

So, the final output is going to be an ASCII spinner. You'll see these characters (in the same spot) repeating until you kill the script.

因此,最终输出将是ASCII微调器。你会看到这些字符(在同一个地方)重复,直到你杀死脚本。

/
-
\
|

#4


2  

Martijn Pieters explanation is excellent. Below is another implementation of the same code you had in the question. it uses itertools.cycle to produce the same result as spinning_cursor. itertools is filled with excellent examples of iterators and functions to help create your own iterators. It might help you understand iterators better.

Martijn Pieters的解释非常好。下面是您在问题中使用的相同代码的另一个实现。它使用itertools.cycle来生成与spinning_cursor相同的结果。 itertools充满了迭代器和函数的优秀示例,以帮助创建自己的迭代器。它可能有助于您更好地理解迭代器。

import sys, time, itertools

for c in itertools.cycle('/-\|'):
    sys.stdout.write(c)
    sys.stdout.flush()
    time.sleep(0.1)
    sys.stdout.write('\b')

#5


2  

the spinning_cursor function returns an iterable (a generator from yield).

spinning_cursor函数返回一个iterable(来自yield的生成器)。

for c in spinning_cursor():

would be the same as

会是一样的

 for i in [1, 2, 3, 4]:

#1


41  

Using yield turns a function into a generator. A generator is a specialized type of iterator. for always loops over iterables, taking each element in turn and assigning it to the name(s) you listed.

使用yield将函数转换为生成器。生成器是一种特殊类型的迭代器。 for always循环遍历iterables,依次获取每个元素并将其分配给您列出的名称。

spinning_cursor() returns a generator, the code inside spinning_cursor() doesn't actually run until you start iterating over the generator. Iterating over a generator means the code in the function is executed until it comes across a yield statement, at which point the result of the expression there is returned as the next value and execution is paused again.

spinning_cursor()返回一个生成器,在您开始迭代生成器之前,spinning_cursor()中的代码实际上不会运行。迭代生成器意味着函数中的代码将被执行,直到遇到yield语句,此时表达式的结果将作为下一个值返回并再次暂停执行。

The for loop does just that, it'll call the equivalent of next() on the generator, until the generator signals it is done by raising StopIteration (which happens when the function returns). Each return value of next() is assigned, in turn, to c.

for循环就是这样,它将在生成器上调用next()的等价物,直到生成器通过提高StopIteration(在函数返回时发生)来发出信号。 next()的每个返回值依次分配给c。

You can see this by creating the generator on in the Python prompt:

您可以通过在Python提示符中创建生成器来查看:

>>> def spinning_cursor():
...     cursor='/-\|'
...     i = 0
...     while 1:
...         yield cursor[i]
...         i = (i + 1) % len(cursor)
... 
>>> sc = spinning_cursor()
>>> sc
<generator object spinning_cursor at 0x107a55eb0>
>>> next(sc)
'/'
>>> next(sc)
'-'
>>> next(sc)
'\\'
>>> next(sc)
'|'

This specific generator never returns, so StopIteration is never raised and the for loop will go on forever unless you kill the script.

这个特定的生成器永远不会返回,因此永远不会引发StopIteration,并且for循环将永远继续,除非您终止该脚本。

#2


4  

In Python, the for statement lets you iterate over elements.

在Python中,for语句允许您迭代元素。

According the documentation :

根据文件:

Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence

Python的for语句按照它们出现在序列中的顺序迭代任何序列(列表或字符串)的项目

Here, the element will be the return value of spinning_cursor().

这里,元素将是spinning_cursor()的返回值。

#3


3  

The for c in spinning_cursor() syntax is a for-each loop. It's going to iterate through each item in the iterator returned by spinning_cursor().

spinning_cursor()语法中的for c是for-each循环。它将遍历spinning_cursor()返回的迭代器中的每个项目。

The inside of the loop will:

循环内部将:

  1. Write the character to standard out and flush so it displays.
  2. 将字符写入标准输出并刷新以显示。
  3. Sleep for a tenth of a second
  4. 睡了十分之一秒
  5. Write \b, which is interpreted as a backspace (deletes the last character). Notice this happens at the end of the loop so it won't be written during the first iteration, and that it shares the flush call in step 1.
  6. 写\ b,它被解释为退格(删除最后一个字符)。请注意,这发生在循环结束时,因此在第一次迭代期间不会写入,并且它在步骤1*享刷新调用。

spinning_cursor() is going to return a generator, which doesn't actually run until you start iterating. It looks like it will loop through '/-\|', in order, forever. It's kind of like having an infinite list to iterate through.

spinning_cursor()将返回一个生成器,在您开始迭代之前,它不会实际运行。看起来它会永远循环遍历'/ - \ |'。这有点像有一个无限的列表来迭代。

So, the final output is going to be an ASCII spinner. You'll see these characters (in the same spot) repeating until you kill the script.

因此,最终输出将是ASCII微调器。你会看到这些字符(在同一个地方)重复,直到你杀死脚本。

/
-
\
|

#4


2  

Martijn Pieters explanation is excellent. Below is another implementation of the same code you had in the question. it uses itertools.cycle to produce the same result as spinning_cursor. itertools is filled with excellent examples of iterators and functions to help create your own iterators. It might help you understand iterators better.

Martijn Pieters的解释非常好。下面是您在问题中使用的相同代码的另一个实现。它使用itertools.cycle来生成与spinning_cursor相同的结果。 itertools充满了迭代器和函数的优秀示例,以帮助创建自己的迭代器。它可能有助于您更好地理解迭代器。

import sys, time, itertools

for c in itertools.cycle('/-\|'):
    sys.stdout.write(c)
    sys.stdout.flush()
    time.sleep(0.1)
    sys.stdout.write('\b')

#5


2  

the spinning_cursor function returns an iterable (a generator from yield).

spinning_cursor函数返回一个iterable(来自yield的生成器)。

for c in spinning_cursor():

would be the same as

会是一样的

 for i in [1, 2, 3, 4]: