Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中,拥有一个iterable和一个迭代器这两个独立对象的目的是什么?_Python_Iterator_Iterable - Fatal编程技术网

在python中,拥有一个iterable和一个迭代器这两个独立对象的目的是什么?

在python中,拥有一个iterable和一个迭代器这两个独立对象的目的是什么?,python,iterator,iterable,Python,Iterator,Iterable,我知道将iterable作为参数传递给iter方法会返回一个迭代器。那么为什么iterable不能始终是迭代器呢。如果没有“下一步”方法,拥有iterable对象的目的是什么?您只能在迭代器上迭代一次。可以将迭代器看作是逐个返回对象的函数。您只能在它们之间循环一次,并且必须按预设顺序循环 Iterables是可以迭代的对象,但与迭代器不同,它们不受迭代的影响,可以通过其他方式访问。可以索引到iterable,但不能索引到迭代器。这意味着我可以访问iterable的第十个、第七个或最后一个元素,而

我知道将iterable作为参数传递给iter方法会返回一个迭代器。那么为什么iterable不能始终是迭代器呢。如果没有“下一步”方法,拥有iterable对象的目的是什么?

您只能在迭代器上迭代一次。可以将迭代器看作是逐个返回对象的函数。您只能在它们之间循环一次,并且必须按预设顺序循环

Iterables是可以迭代的对象,但与迭代器不同,它们不受迭代的影响,可以通过其他方式访问。可以索引到iterable,但不能索引到迭代器。这意味着我可以访问iterable的第十个、第七个或最后一个元素,而不需要任何其他元素,但我需要循环遍历迭代器的前面元素来访问这些元素


可以找到更深入的解释

您只能在迭代器上迭代一次。可以将迭代器看作是逐个返回对象的函数。您只能在它们之间循环一次,并且必须按预设顺序循环

Iterables是可以迭代的对象,但与迭代器不同,它们不受迭代的影响,可以通过其他方式访问。可以索引到iterable,但不能索引到迭代器。这意味着我可以访问iterable的第十个、第七个或最后一个元素,而不需要任何其他元素,但我需要循环遍历迭代器的前面元素来访问这些元素


可以找到更深入的解释

将iterable视为对象的特殊天赋。例如,当使用for循环或使用解包时,可以对其进行迭代


迭代器是负责从某个对象传递数据的对象。这意味着您可以让这些对象中的几个都从同一个底层对象传递独立的数据。

将iterable视为一个对象的特殊天赋。例如,当使用for循环或使用解包时,可以对其进行迭代


迭代器是负责从某个对象传递数据的对象。这意味着您可以让这些对象中的几个都从同一底层对象传递独立的数据。

类根据从_uiter__;方法返回的内容决定如何迭代它们。有时iterables是自己的迭代器,例如文件对象,有时iterables创建单独的迭代器对象,例如列表。由开发人员决定哪种实现最好

对于文件对象,它只有一个当前位置,读取将始终在该位置继续。使用唯一的迭代器来持续交换文件位置以正确读取是没有意义的。与之类似的是,流媒体协议根本不能倒带

生成器类似于文件对象和流。它们不能改变位置,所以它们可以成为自己的迭代器

但对于列表对象,如果一次只有一个代码实体可以遍历它,那就很奇怪了。列表对象返回一个单独的迭代器,该迭代器只跟踪该迭代器在列表中的当前位置

这两种迭代方法之间的差异可能会破坏代码,或者至少会降低代码的可用性。考虑一个与多行记录一起工作的文件处理器。它可以使用内部for继续迭代文件的行

def file_processor(f):
    for line in f:
        if line.startswith('newrecord'):
            for line in f:
                print(line,strip())
                if line.startswith('endrecord'):
                    break
但是如果您传入一个列表,则会中断,因为该内部for将再次从列表的顶部开始。通过让它显式地获得迭代器,可以将其更改为处理更多对象

def file_processor(f):
    iter_f = iter(f)
    for line in iter_f:
        if line.startswith('newrecord'):
            for line in iter_f:
                print(line,strip())
                if line.startswith('endrecord'):
                    break

类根据从_iter__方法返回的内容决定如何迭代它们。有时iterables是自己的迭代器,例如文件对象,有时iterables创建单独的迭代器对象,例如列表。由开发人员决定哪种实现最好

对于文件对象,它只有一个当前位置,读取将始终在该位置继续。使用唯一的迭代器来持续交换文件位置以正确读取是没有意义的。与之类似的是,流媒体协议根本不能倒带

生成器类似于文件对象和流。它们不能改变位置,所以它们可以成为自己的迭代器

但对于列表对象,如果一次只有一个代码实体可以遍历它,那就很奇怪了。列表对象返回一个单独的迭代器,该迭代器只跟踪该迭代器在列表中的当前位置

这两种迭代方法之间的差异可能会破坏代码,或者至少会降低代码的可用性。考虑一个与多行记录一起工作的文件处理器。它可以使用内部for继续迭代文件的行

def file_processor(f):
    for line in f:
        if line.startswith('newrecord'):
            for line in f:
                print(line,strip())
                if line.startswith('endrecord'):
                    break
但是如果您传入一个列表,则会中断,因为该内部for将再次从列表的顶部开始。你可以把它改成工作模式 通过显式地获取迭代器来创建更多的对象

def file_processor(f):
    iter_f = iter(f)
    for line in iter_f:
        if line.startswith('newrecord'):
            for line in iter_f:
                print(line,strip())
                if line.startswith('endrecord'):
                    break

作为一个本身不是迭代器的可迭代的例子,让我们列出一个列表。列表上的迭代器需要包含状态,即要获取的下一项的索引号。列表本身不包含此状态。但让我们看一个例子,在这个例子中我们有一个列表,并从中生成一个迭代器,并用它代替列表,以演示如果列表本身是迭代器,否则工作代码将如何中断

关键的问题是,我们不止一次地重复这个列表。在本例中,循环是嵌套的,但如果按顺序遇到循环,则会出现类似的问题

names = ["Brontolo", "Cucciolo", "Dotto", "Eolo",
         "Gongolo", "Mammolo", "Pisolo"]  # This is not an iterator...

names = iter(names)  # ... but let's simulate what would happen if it was.

for name1 in names:
    for name2 in names:
        if name1 == name2:
            print(f"{name1} looks in the mirror")
        else:
            print(f"{name1} looks at {name2}")
输出:

布朗托洛看着库奇奥洛 布朗托洛看着多托 布朗托洛看着埃洛 布朗托洛看着贡戈洛 Brontolo看着Mammolo 布朗托洛看着皮索洛 这根本不能正常工作,因为这两个循环共享同一个迭代器。在外部name1循环的第一次迭代中,索引将递增。然后,内部name2循环会遗漏第一项,并从第二项循环到最后一项。然后,在外循环的下一次尝试迭代中,索引已经指向列表的末尾,循环终止


现在注释掉names=iternames语句,当然它可以按预期工作。这一次发生的情况是,由于列表没有uuu next_uuuu方法,因此当遇到names:中类似于name1的语句时,会动态生成一个新的迭代器以生成name1的值,而该迭代器包含索引,而不是列表本身。在外循环的每一次迭代中,为内部循环同样生成完全分离的迭代器对象,然后可以独立迭代。

< P>作为一个本身不是迭代器的可迭代的例子,让我们列出一个列表。列表上的迭代器需要包含状态,即要获取的下一项的索引号。列表本身不包含此状态。但让我们看一个例子,在这个例子中我们有一个列表,并从中生成一个迭代器,并用它代替列表,以演示如果列表本身是迭代器,否则工作代码将如何中断

关键的问题是,我们不止一次地重复这个列表。在本例中,循环是嵌套的,但如果按顺序遇到循环,则会出现类似的问题

names = ["Brontolo", "Cucciolo", "Dotto", "Eolo",
         "Gongolo", "Mammolo", "Pisolo"]  # This is not an iterator...

names = iter(names)  # ... but let's simulate what would happen if it was.

for name1 in names:
    for name2 in names:
        if name1 == name2:
            print(f"{name1} looks in the mirror")
        else:
            print(f"{name1} looks at {name2}")
输出:

布朗托洛看着库奇奥洛 布朗托洛看着多托 布朗托洛看着埃洛 布朗托洛看着贡戈洛 Brontolo看着Mammolo 布朗托洛看着皮索洛 这根本不能正常工作,因为这两个循环共享同一个迭代器。在外部name1循环的第一次迭代中,索引将递增。然后,内部name2循环会遗漏第一项,并从第二项循环到最后一项。然后,在外循环的下一次尝试迭代中,索引已经指向列表的末尾,循环终止

现在注释掉names=iternames语句,当然它可以按预期工作。这一次发生的情况是,由于列表没有uuu next_uuuu方法,因此当遇到names:中类似于name1的语句时,会动态生成一个新的迭代器以生成name1的值,而该迭代器包含索引,而不是列表本身。在外循环的每次迭代中,都会为内循环生成一个完全独立的迭代器对象,然后可以独立地对其进行迭代