从一个列表生成多个列表

3
什么是追加列表的最佳方法?
A = [1,2,3,4,5]

并获取这样的列表;
B = [[1], [1, 2], [1,2,3], [1,2,3,4], [1,2,3,4,5]]

如果你想要所有可能的组合,你应该看一下 itertools:https://docs.python.org/3/library/itertools.html - Loïc
@Loïc:不,他想要所有可能的初始化。 - Willem Van Onsem
5个回答

9

只需使用切片的列表推导式

B = [A[:i] for i in range(1, len(A) + 1)]

4
另外一个列表推导式,避免太多地操作索引。
A = [1,2,3,4,5]

B = [A[:i+1] for i, _ in enumerate(A)]
print(B)  # [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

3
A = [1,2,3,4,5]

B = []

for x in range(1,len(A)+1):
    B.append(list(A[0:x]))

print(B)

输出:

[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

1
也许我太草率地点了踩。正如你所说,对我来说,这个解决方案不是Pythonic的,因此不是“正确”的(对我来说),即使它是有效的。我认为每种语言都有其“风格”,我们的职责是尽力保留它。话虽如此,我并不是一个“大师”或专家。 - horro

3

我认为最好的方法,也是最基本的方法,是使用List Comprehensions

A = [1,2,3,4,5]
B = [A[:i+1] for i in range(len(A))]
print B

输出:

[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

顺便提一下,对于你上面给出的例子,即使这样也有用:
B = [A[:i] for i in A]

2

您在此描述的是某些函数式编程语言中所称的“inits”。

我们可以构建一个在无限生成器上工作且具有延迟加载的“inits”函数,如下所示:

from itertools import islice

def inits(xs):
    ls = []
    for i,x in enumerate(xs,1):
        ls.append(x)
        yield islice(ls,i)

对于您的情况,我们可以执行map(list,...),然后在结果上执行list(..)

>>> list(map(list,inits(A)))
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

这种方法的优点是它适用于无限生成器,以及可以枚举但不支持切片的集合。此外,内存在不同的islice之间共享,因此我们不会构造显式列表,除非我们明确需要(就像上面的示例中一样)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接