在列表中解压缩迭代器的Python方法

rus*_*ro1 3 python list unpack python-3.x iterable-unpacking

我试图找出在列表中解包迭代器的pythonic方法是什么。

例如:

my_iterator = zip([1, 2, 3, 4], [1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)

我提供了以下几种在列表中解压缩迭代器的方法:

1)

my_list = [*my_iterator]
Run Code Online (Sandbox Code Playgroud)

2)

my_list = [e for e in my_iterator]
Run Code Online (Sandbox Code Playgroud)

3)

my_list = list(my_iterator)
Run Code Online (Sandbox Code Playgroud)

No 1)是我最喜欢的方法,因为它减少了代码,但是我想知道这是否也是pythonic方法。或者,也许除了Python 3之外,还有另一种方法可以实现这一目标?

Mat*_* L. 8

这可能是将迭代器转换为列表最快方法的重复,但是您的问题有所不同,因为您询问哪个是最Python的。可以接受的答案已经list(my_iterator)结束,[e for e in my_iterator]因为先验在引擎盖下运行。一位评论者建议[*my_iterator]比更快list(my_iterator),因此您可能要测试一下。我的普遍投票是,它们都是同样具有Python风格,因此在您的用例中,我会选择两者中较快的一个。较旧的答案也可能过时。


rus*_*ro1 5

在探索了更多主题之后,我得出了一些结论。

应该有一种——最好只有一种——明显的方法来做到这一点

蟒蛇之禅

决定哪个选项是“pythonic”应该考虑一些标准:

  • 多么明确,
  • 简单的,
  • 它是可读的。

在所有标准中获胜的明显“pythonic”选项是选项编号 3):

列表 = 列表(my_iterator)

这就是为什么“明显”没有 3) 是 pythonic 的原因:

  • 选项 3) 接近自然语言,让您“立即”思考输出是什么。
  • 选项 2)(使用列表推导式)如果您第一次看到该行代码将带您多读一点并多加注意。例如,当我想添加一些额外的步骤(使用迭代元素调用函数或使用 if 语句进行一些检查)时,我使用列表理解,所以当我看到列表理解时,我会检查内部或任何可能的函数调用如果声明。
  • 选项 1)(使用 * 解包)星号运算符如果您不经常使用它可能会有点混乱,在 Python 中使用星号4 种情况

    1. 用于乘法和幂运算。
    2. 用于重复扩展列表类型容器。
    3. 用于使用可变参数。(所谓的“包装”)
    4. 用于打开容器。

另一个很好的论点是python 文档本身,我做了一些统计来检查文档选择了哪些选项,为此我选择了 4 个内置迭代器和模块itertools 中的所有内容(使用如下:)itertools.来看看如何它们被解压到一个列表中:

  • 地图
  • 范围
  • 筛选
  • 枚举
  • 迭代工具。

在浏览文档后,我发现:使用选项 1) 和 2) 在列表中解压了 0 个迭代器,使用选项 3) 解压了 35 个迭代器。

在此处输入图片说明

结论

在列表中解压迭代器的 Pythonic 方法是: my_list = list(my_iterator)


GZ0*_*GZ0 5

虽然解包运算符*不常用于将单个可迭代对象解包到列表中(因此[*it]可读性比 稍差list(it)),但在其他几种情况下它很方便且更具 Python 风格:

1. 将可迭代对象解包为单个列表/元组/集合,并添加其他值:

mixed_list = [a, *it, b]
Run Code Online (Sandbox Code Playgroud)

这比

mixed_list = [a]
mixed_list.extend(it)
mixed_list.append(b)
Run Code Online (Sandbox Code Playgroud)

2. 将多个可迭代+值解压到列表/元组/集合中

mixed_list = [*it1, *it2, a, b, ... ]
Run Code Online (Sandbox Code Playgroud)

这与第一种情况类似。

3. 将可迭代对象解包到列表中,排除元素

first, *rest = it
Run Code Online (Sandbox Code Playgroud)

it这会提取into的第一个元素first并将其余元素解压到列表中。甚至可以做

_, *mid, last = it
Run Code Online (Sandbox Code Playgroud)

这会将 的第一个元素转储it到无关变量 中_,将最后一个元素保存到 中last,并将其余元素解压到列表中mid

4. 在一条语句中对可迭代对象的多个级别进行嵌套解包

it = (0, range(5), 3)
a1, (*a2,), a3 = it          # Unpack the second element of it into a list a2
e1, (first, *rest), e3 = it  # Separate the first element from the rest while unpacking it[1]
Run Code Online (Sandbox Code Playgroud)

这也可以用在for语句中:

from itertools import groupby

s = "Axyz123Bcba345D"
for k, (first, *rest) in groupby(s, key=str.isalpha):
    ...
Run Code Online (Sandbox Code Playgroud)