首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Iterable vs序列

Python Iterable vs序列
EN

Stack Overflow用户
提问于 2022-05-08 00:36:57
回答 2查看 5.3K关注 0票数 29

当我暗示IterableSequence时,我不明白两者的区别。

这两者之间的主要区别是什么?什么时候使用哪一种?

我认为set是一个Iterable而不是Sequence,有什么内置的数据类型是Sequence而不是Iterable吗?

代码语言:javascript
复制
def foo(baz: Sequence[float]):
  ...

# What is the difference?
def bar(baz: Iterable[float]):
  ...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-08 04:34:32

SequenceIterable抽象基类(也可以用作类型注释)遵循序列可迭代的定义。具体而言:

  • Iterable是定义__iter__ __getitem__的任何对象。
  • Sequence是定义__getitem____len__的任何对象。根据定义,任何序列都是可迭代的。Sequence类还定义了其他方法,如调用两个必需方法的__contains____reversed__

下面是一些例子:

  • listtuplestr是最常见的序列。
  • 一些内置的迭代器不是序列。例如,reversed返回不能订阅的reversed对象(或列表的list_reverseiterator )。
票数 25
EN

Stack Overflow用户

发布于 2022-11-17 15:09:20

在编写带有items参数的函数/方法时,我通常更喜欢Iterable而不是Sequence。这就是为什么,我希望这将有助于理解不同之处。

假设my_func_1是:

代码语言:javascript
复制
from typing import Iterable
def my_func_1(items: Iterable[int]) -> None:
    for item in items:
        ...
        if condition:
            break
    return

Iterable为调用者提供了最大的可能性。正确的呼叫包括:

代码语言:javascript
复制
my_func_1((1, 2, 3)) # tuple is Sequence, Collection, Iterator
my_func_1([1, 2, 3]) # list is MutableSequence, Sequence, Collection, Iterator
my_func_1({1, 2, 3}) # set is Collection, Iterator
my_func_1(my_dict) # dict is Mapping, Collection, Iterator
my_func_1(my_dict.keys()) # dict.keys() is MappingKeys, Set, Collection, Iterator
my_func_1(range(10)) # range is Sequence, Collection, Iterator
my_func_1(x**2 for x in range(100)) # "strict' Iterator, i.e. neither a Collection nor a Sequence
... 

..。因为一切都是Iterable

给函数调用者的隐式消息是:按原样传输数据,只是不对其进行转换。

如果调用者没有数据作为Sequence (例如tuplelist)或非Sequence Collection (例如set),并且由于迭代在StopIteration之前中断,如果他提供了一个“严格的”Iterator,那么它也会更好地执行。

但是,如果函数算法(例如my_func_2)需要多个迭代,那么如果调用方提供了“严格”的Iterator,那么Iterable就会失败,因为第一次迭代会耗尽它。因此,请使用Collection

代码语言:javascript
复制
from typing import Collection
def my_func_2(items: Collection[int]) -> None:
    for item in items:
        ...
    for item in items:
        ...
    return

如果函数算法(my_func_3)必须通过索引访问特定项),那么如果调用方提供集合、Mapping或“严格”的Iterator,则IterableCollection都将失败。因此,请使用Sequence

代码语言:javascript
复制
from typing import Sequence
def my_func_3(items: Sequence[int]) -> None:
    return items[5]

结论:策略是:“使用功能所能处理的最通用类型”。不要忘记,所有这些仅仅是关于输入,以帮助静态类型检查器报告不正确的调用(例如,在需要set时使用Sequence )。然后,调用方有责任在必要时转换数据,例如:

代码语言:javascript
复制
my_func_3(tuple(x**2 for x in range(100)))

实际上,所有这些实际上都是关于在缩放项的长度时的性能。如果可能的话,总是更喜欢Iterator。工作表现应作为日常任务处理,而不是作为消防队员工作队处理。

在这个方向上,您可能会遇到这样的情况:函数只处理空用例并委托其他用例,并且不希望将项转换为CollectionSequence。然后做这样的事情:

代码语言:javascript
复制
from more_itertools import spy
def my_func_4(items: Iterable[int]) -> None:
    (first, items) = spy(items)
    if not first: # i.e. items is empty
        ...
    else:
        my_func_1(items) # Here 'items' is always a 'strict' Iterator
    return
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72157296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档