繁体   English   中英

如何在Python中创建空列表的列表或元组?

[英]How to create a list or tuple of empty lists in Python?

我需要逐步填充列表或列表元组。 看起来像这样的东西:

result = []
firstTime = True
for i in range(x):
    for j in someListOfElements:
        if firstTime:
            result.append([f(j)])
        else:
            result[i].append(j)

为了使它更简洁更优雅,我想我会预先分配一个空列表列表

result = createListOfEmptyLists(x)
for i in range(x):
    for j in someListOfElements:
        result[i].append(j)

预分配部分对我来说并不明显。 当我做result = [[]] * x ,我收到一个对同一列表的x引用列表,以便输出以下内容

result[0].append(10)
print result

是:

[[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]]

我可以使用循环( result = [[] for i in range(x)] ),但我想知道是否存在“无循环”解决方案。

是获得我正在寻找的唯一方法

result = [list(someListOfElements) for _ in xrange(x)]

这将生成x个不同的列表,每个列表都有someListOfElements列表的副本( someListOfElements列表中的每个项目都是引用,但其中的列表是副本)。

如果它更有意义,请考虑使用copy.deepcopy(someListOfElements)

生成器和列表推导和事物被认为是非常pythonic

有没有真正的方式没有某种形式的循环来创建这样一个列表。 但是,有多种隐藏循环的方法,就像[[]] * x隐藏循环一样。 有一个列表理解,它将表达式“隐藏”在一个表达式中(幸运的是它仍然显而易见。)还有map(list, [[]]*x) ,它有两个隐藏的循环( [[]] * xmap中的一个使用list()创建每个列表的副本。)

还有可能不事先创建列表列表。 其他答案已经涵盖了简单的方法,但如果不能满足您的需求,还有其他方法。 例如,您可以根据需要创建一个将空列表附加到result列表的函数,并调用:

def append(L, idx, item):
    while len(L) <= idx:
        L.append([])
    L[idx].append(item)

for i in range(x):
    for j in someListOfElements:
        append(result, i, j)

或者您可以使用collections.defaultdict(list)而不是列表:

import collections
result = collections.defaultdict(list)
for i in range(x):
    for j in someListOfElements:
        result[i].append(j)

这样做的好处是使用已经存在的类型,这样做的工作量较少,但它确实意味着你现在有一个dict(用整数索引)而不是列表,这可能是也可能不是你想要的。 或者你可以创建一个类似于列表的类,但是将新列表附加到自身而不是引发IndexError,例如:

import UserList
class defaultlist(UserList.UserList):
    def __getitem__(self, idx):
        while len(self) <= idx:
            self.append([])
        return UserList.UserList.__getitem__(self, idx)

result = defaultlist()
for i in range(x):
    for j in someListOfElements:
        result[i].append(j)

你可以写一个快速生成器函数。 除了这个特殊情况之外,这将有其他用途,所以我会稍微概括一下。 挖这个:

def create(n, constructor=list):
    for _ in xrange(n):
        yield constructor()

然后列出一个列表,

result = list(create(10))

列出空的dicts,

result = list(create(20, dict))

并且(为了完整起见)列出空的Foos,

result = list(create(30, Foo))

当然,你也可以制作上述任何一个元组。 扩展它以允许构造函数的参数也不会太难。 我可能会接受一个接受索引的函数并返回要传递给构造函数的参数。

最后一个想法是,因为我们放置在constructor上的唯一要求是它是一个可调用的,你甚至可以传递它在列表中返回你想要的东西。 例如,一种绑定方法,用于从数据库查询中提取结果。 这是非常有用的三行代码。

为什么不通过在适当的循环中附加列表来保持简单

result = []
for i in range(x):
    result.append([])
    for j in someListOfElements:
        result[i].append(j)

[编辑:添加示例]

>>> someListOfElements = ['a', 'b', 'c']
>>> x = 3
>>> result = []
>>> for i in range(x):
...     result.append([])
...     for j in someListOfElements:
...         result[i].append(j)
... 
>>> 
>>> result
[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]

请包含可运行的示例代码,以便我们可以自己运行代码以快速查看您想要执行的操作。 看起来你只想要这个:

result = []
for i in range(x):
    data = []
    for j in someListOfElements:
        data.append(j)
    # or data = [j for j in someListOfElements]
    result.append(data)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM