可迭代的 Python for 循环如何工作?(`用于 feed.entry 中的派对`)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1292189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:51:59  来源:igfitidea点击:

How does a Python for loop with iterable work? (`for party in feed.entry`)

pythonfor-loopiterable

提问by ymv

What does for party in feed.entrysignify and how does this for-loop actually work?

for party in feed.entry这个 for 循环究竟意味着什么以及它是如何工作的?

for party in feed.entry:
    print party.location.address.text

(I am used to C++ style for-loops, but the Python loops have left me confused.)

(我习惯于 C++ 风格的 for 循环,但 Python 循环让我感到困惑。)

回答by ymv

feed.entry is property of feed and it's value is (if it's not, this code will fail) object implementing iteration protocol (array, for example) and has itermethod, which returns iterator object

feed.entry 是 feed 的属性,它的值是(如果不是,此代码将失败)实现迭代协议的对象(例如数组)并具有iter方法,该方法返回迭代器对象

Iterator has next() method, returning next element or raising exception, so python for loop is actually:

Iterator 有 next() 方法,返回下一个元素或引发异常,所以 python for 循环实际上是:

iterator = feed.entry.__iter__()
while True:
    try:
        party = iterator.next()
    except StopIteration:
        # StopIteration exception is raised after last element
        break

    # loop code
    print party.location.address.text

回答by Drakosha

feed.entry is something that allows iteration, and contains objects of some type. This is roughly similar to c++:

feed.entry 是允许迭代的东西,并包含某种类型的对象。这与 c++ 大致相似:

for (feed::iterator party = feed.entry.begin(); party != feed.entry.end(); ++party) {
   cout << (*party).location.address.text;
}

回答by Bartosz Radaczyński

To add my 0.05$ to the previous answers you might also want to take a look at the enumerate builtin function

要将我的 0.05$ 添加到以前的答案中,您可能还想查看enumerate 内置函数

for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']):
    print i, season

0 Spring
1 Summer
2 Fall
3 Winter

回答by Pierre-Jean Coudert

partysimply iterates over the iterablefeed.entry

派对只是迭代可迭代的feed.entry

Take a look at Dive into Pythonexplainations.

看看深入 Python 的解释。

回答by MisterMiyagi

A forstatementin Python always operates on an iterable-- which means it can provide an iteratorover its items. The forstatement successively fetches the nextelement from the iterator, assigns it to the target name(s) and runs the suite ("body") with that.

Python 中的for语句总是对可迭代对象进行操作——这意味着它可以为其项提供迭代器。该for语句连续next从迭代器中获取元素,将其分配给目标名称并使用该名称运行套件(“body”)。

#   |name|   |iterable|
for party in feed.entry:
    # body...
    print(party.location.address.text)

In the example, feed.entryis the iterable, partyis the target name and print ...is the suite. The iterator is automatically requested by the forstatement, and holds the iteration state - e.g. the index of the next element if the iterable is a list.

在示例中,feed.entry是可迭代的,party是目标名称,print ...是套件。迭代器由for语句自动请求,并保存迭代状态 - 例如,如果可迭代对象是列表,则为下一个元素的索引。



If you are coming from C++, a classical for (int i = 0; i < 10; ++i)looprepresents external iteration: the iteration state iis kept outside of the iterable. This corresponds to Python's whileloop:

如果您来自 C++,经典for (int i = 0; i < 10; ++i)循环代表外部迭代:迭代状态i保持在可迭代对象之外。这对应于 Python 的while循环:

# for (int i = 0; i < 10; ++i)
i = 0
while i < 10:
    i += 1
    # access the state of an iterable here

The newer for (auto party : entry)range looprepresents internal iteration: the iteration state is kept by a separate iterator. This corresponds to Python's forloop. However, the iterable/iterator protocol differs notably: Python's foruses iter(iterable)to get an iterator, which should support next(iterator)- either returning an element or raising StopIteration.

较新的for (auto party : entry)范围循环代表内部迭代:迭代状态由单独的迭代器保持。这对应于 Python 的for循环。然而,迭代/迭代器协议显着不同:Python的for应用iter(iterable)来获得一个迭代器,它应该支持next(iterator)-无论是返回一个元素或提高StopIteration

Written in Python, the definition of the forstatementcorresponds to this:

用Python写的,for语句定义是这样对应的:

# for party in feed.entry:
__iterator = iter(feed.entry)  # iterator -- not visible in containing scope
__iterating = True             # graceful exit to enter `else` clause
while __iterating:
    try:                          # attempt to...
        item = next(__iterator)   # ... get the next item
    except StopIteration:         # ... or stop
        __iterating = False       #     with a graceful exit
    else:
        party = item
        <suite>                # run the body with names bound
else:                          # entered in a graceful exit only
    <else suite>

(Note that the entire block from __iterating = Trueto __iterating = Falseis not "visible" to the containing scope. Implementations use various optimisations, such as CPython allowing builtin iterators to return a C NULLinstead of raising a Python StopIteration.)

(请注意,从__iterating = Trueto的整个块__iterating = False对包含的范围来说不是“可见的”。实现使用各种优化,例如 CPython 允许内置迭代器返回 CNULL而不是引发 PythonStopIteration。)

The forstatement just defines howiterable and iterator are used. If you are mostly familiar with external iteration, it helps looking at iterable and iterator as well.

for语句仅定义iterable 和 iterator 的使用方式。如果您最熟悉外部迭代,那么查看 iterable 和 iterator 也很有帮助。



The iter(iterable)call has multiple ways to derive an iterator- this is as if iterwere overloaded for various structural types.

iter(iterable)调用有多种方法可以派生迭代器——这就像iter为各种结构类型重载一样。

  • If type(iterable).__iter__is defined, it is called as a method and the result is used as the iterator.

  • If type(iterable).__getitem__is defined, it is wrapped by a generic iterator type that returns iterable[0], iterable[1], ... and raises StopIterationif IndexErroris raised when indexing.

  • 如果type(iterable).__iter__已定义,则将其作为方法调用,并将结果用作迭代器。

  • Iftype(iterable).__getitem__被定义,它被一个返回iterable[0], iterable[1], ...的泛型迭代器类型包装,并在索引时引发StopIterationif IndexError

Either way, iterreturns an iteratoror raises TypeError. An iterator is anytype that defines __iter__(for reusability) and __next__(for the actual iteration). In general, iterators are objects that may hold state to compute the __next__item. For example, a list iterator corresponds to this object:

无论哪种方式,都iter返回一个迭代器或 raises TypeError。迭代器是定义(为了可重用性)和(为了实际迭代)的任何类型。通常,迭代器是可以保存状态以计算项目的对象。例如,一个列表迭代器对应于这个对象:__iter____next____next__

class ListIterator:
    """Python equivalent of ``iter(:list)``"""
    # iterator holds iteration state - e.g. iterable and current index
    def __init__(self, iterable: list):
        self.iterable = iterable
        self.index = 0

    # __next__ fetches item and advances iteration state - e.g. index += 1
    def __next__(self):
        # attempt to produce an item
        try:
            item = self.iterable[self.index]
        except IndexError:  # translate indexing protocol to iteration protocol
            raise StopIteration
        # update iteration state
        self.index += 1
        return item

    # iterators can be iterated on in ``for`` statements etc.
    def __iter__(self):
        return self

(Note that one would idiomatically write such an object as a generator function.)

(请注意,人们习惯性地将这样的对象编写为生成器函数。)

Indexing a list or incrementing some pointer is only a very basic example of the iterable/iterator protocol. For example, an iterator could be stateless and use random.random()in __next__to produce an infinite stream of random numbers. Iterators can also hold state of external information, and iteratively traverse a file system, for example.

索引列表或增加某个指针只是可迭代/迭代器协议的一个非常基本的例子。例如,一个迭代器可能是无状态的,使用random.random()__next__产生随机数的无限流。例如,迭代器还可以保存外部信息的状态,并迭代地遍历文件系统。

回答by Carl Smith

I just wanted to provide a more generic explanation for people new to this.

我只是想为刚接触这个的人提供一个更通用的解释。

Syntactically, the forloop looks like...

从语法上讲,for循环看起来像......

for <name to be assigned to> in <some sequence>:

    <block of code, optionally referencing the name>

The interpreter runs the block once for each item in the sequence (anything that can iterated over). Each time it runs the block, it first assigns the next object in the sequence to the name, which can be any valid variable name.

解释器为序列中的每个项目(任何可以迭代的项目)运行一次块。每次运行块时,它首先将序列中的下一个对象分配给名称,该名称可以是任何有效的变量名称。

Doing for each in (1, 2, 3): print(each)is [more or less] the same as doing...

for each in (1, 2, 3): print(each)[或多或少] 与做...相同

i = 0
sequence = (1, 2, 3)
while True:
    try:
        each = sequence[i]
        print(each)
        i += 1
    except IndexError: pass

You can also unpack arguments in the assignment part. In the same way that you can do stuff like...

您还可以在赋值部分解压缩参数。就像你可以做这样的事情一样......

a, b = 1, 2

...you can also do stuff like...

......你也可以做这样的事情......

for a, b in [(1, 2), (3, 4), (5, 6)]: print(a + b)

...which prints...

...打印...

3
7
11

回答by ramosg

In Python, forbucles aren't like the C/C++ ones, they're most like PHP's foreach. What you do isn't iterate like in a whilewith "(initialization; condition; increment)", it simply iterates over each element in a list (strings are ITERABLE like lists).

在 Python 中,因为bucles 不像 C/C++ 的,它们最像 PHP 的foreach。你所做的不是像“(初始化;条件;增量)”那样在一段时间内迭代,它只是迭代列表中的每个元素(字符串像列表一样是可迭代的)。

For example:

例如:

for number in range(5):
    print number

will output

会输出

0
1
2
3
4

回答by ars

Python's forloop works with iterators, which must implement the iteratorprotocol. For more details see:

Python 的for循环使用iterators,它必须实现iterator协议。有关更多详细信息,请参阅: