【问题标题】:How to create a list or tuple of empty lists in Python?如何在 Python 中创建空列表的列表或元组?
【发布时间】:2010-10-07 08:48:41
【问题描述】:

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

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)]),但我想知道是否存在“无循环”解决方案。

是获得我想要的东西的唯一方法

【问题讨论】:

  • 可能有更好的方法来完成这一切,但仅凭这段代码很难说清楚。
  • 请问,列表理解有什么问题?我不认为列表乘法更优雅或(更多)更快(尽管它可以更快,因为在乘法列表时没有实例化)。
  • 对于空列表的列表,有[ [ [] for c in range(cols) ] for r in range(rows) ]。

标签: memory-management python


【解决方案1】:
result = [list(someListOfElements) for _ in xrange(x)]

这将创建 x 个不同的列表,每个列表都有一个 someListOfElements 列表的副本(该列表中的每个项目都是引用,但其所在的列表是一个副本)。

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

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

【讨论】:

  • +1:列表理解不是唯一的解决方案,只是最pythonic,我敢说最正确解决方案。
  • 要使用n 空列表填充列表,请执行result = [[] for _ in xrange(n)]
  • 对于 python3,result = [someListOfElements for _ in range(desired_length)] 有效。
  • @stephenb 这是有效的python,但它没有做同样的事情。它制作了一个列表,其中每个元素都指向 someListOfElements,而不是它们的副本。
  • 对于上面@gsamaras 给出的解决方案,如果在Python 3 中使用:result = [[] for _ in range(n)],因为xrange 已被弃用且不起作用。
【解决方案2】:

如果没有 some 排序循环,真的没有办法创建这样的列表。不过,隐藏循环有多种方法,就像 [[]] * x 隐藏循环一样。有列表理解,它“隐藏”了表达式中的循环(谢天谢地,它仍然很明显。)还有 map(list, [[]]*x) 有 两个 隐藏循环([[]] * x 中的一个和map 使用 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)

【讨论】:

  • 请注意[[]] * count 确实不创建空列表的列表。它创建一个对同一个空列表的引用列表。向其中一个列表添加一个条目,将它们添加到所有列表中。
【解决方案3】:

您可以编写一个快速生成器函数。除了这种特殊情况外,这还有其他用途,所以我将对其进行一些概括。挖这个:

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

然后做一个列表列表,

result = list(create(10))

制作一个空字典列表,

result = list(create(20, dict))

并且(为了完整起见)制作一个空 Foos 的列表,

result = list(create(30, Foo))

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

最后一个想法是,因为我们对 constructor 的唯一要求是它是可调用的,所以您甚至可以将任何返回列表中所需内容的东西传递给它。例如,从数据库查询中提取结果的绑定方法。这是一个非常有用的小三行代码。

【讨论】:

    【解决方案4】:

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

    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']]
    

    【讨论】:

    • list([]) 有点多余。
    【解决方案5】:

    请包含可运行示例代码,这样我们就可以自己运行代码以快速准确地查看您想要做什么。看起来你只是想要这个:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 2017-03-27
      • 2011-11-10
      相关资源
      最近更新 更多