如何在 Python 中创建空列表的列表或元组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3880037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a list or tuple of empty lists in Python?
提问by Boris Gorelik
I need to incrementally fill a list or a tuple of lists. Something that looks like this:
我需要逐步填充列表或列表元组。看起来像这样的东西:
result = []
firstTime = True
for i in range(x):
for j in someListOfElements:
if firstTime:
result.append([f(j)])
else:
result[i].append(j)
In order to make it less verbose an more elegant, I thought I will preallocate a list of empty lists
为了让它不那么冗长更优雅,我想我会预先分配一个空列表的列表
result = createListOfEmptyLists(x)
for i in range(x):
for j in someListOfElements:
result[i].append(j)
The preallocation part isn't obvious to me. When I do result = [[]] * x, I receive a list of xreferences to the same list, so that the output of the following
预分配部分对我来说并不明显。当我这样做时result = [[]] * x,我会收到x对同一列表的引用列表,以便输出以下内容
result[0].append(10)
print result
is:
是:
[[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]]
I can use a loop (result = [[] for i in range(x)]), but I wonder whether a "loopless" solution exists.
我可以使用循环 ( result = [[] for i in range(x)]),但我想知道是否存在“无循环”解决方案。
Is the only way to get what I'm looking for
是获得我正在寻找的东西的唯一途径
采纳答案by Will
result = [list(someListOfElements) for _ in xrange(x)]
This will make x distinct lists, each with a copy of someListOfElementslist (each item in that list is by reference, but the list its in is a copy).
这将生成 x 个不同的列表,每个列表都有一个someListOfElements列表的副本(该列表中的每个项目都是引用,但其所在的列表是一个副本)。
If it makes more sense, consider using copy.deepcopy(someListOfElements)
如果更有意义,请考虑使用 copy.deepcopy(someListOfElements)
Generators and list comprehensions and things are considered quite pythonic.
生成器和列表推导式和事物被认为是非常Pythonic 的。
回答by pyfunc
Why not keep it simple by just appending the list in appropriate loop
为什么不通过将列表附加到适当的循环中来保持简单
result = []
for i in range(x):
result.append([])
for j in someListOfElements:
result[i].append(j)
[Edit: Adding example]
[编辑:添加示例]
>>> 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']]
回答by Glenn Maynard
Please include runnablesample code, so we can run the code ourself to quickly see exactly what it is you want to do. It looks like you just want this:
请包含可运行的示例代码,以便我们可以自己运行代码以快速查看您想要做什么。看起来你只想要这个:
result = []
for i in range(x):
data = []
for j in someListOfElements:
data.append(j)
# or data = [j for j in someListOfElements]
result.append(data)
回答by Thomas Wouters
There's not really a way to create such a list without a loop of somesort. There are multiple ways of hiding the loop, though, just like [[]] * xhides the loop. There's the list comprehension, which "hides" the loop in an expression (bit it's thankfully still obvious.) There's also map(list, [[]]*x)which has twohidden loops (the one in [[]] * xand the one in mapthat creates a copy of each list using list().)
有没有真正的方式没有的循环来创建这样一个列表的一些排序。但是,有多种隐藏循环的方法,就像[[]] * x隐藏循环一样。有列表推导式,它在表达式中“隐藏”了循环(值得庆幸的是它仍然很明显。)还有map(list, [[]]*x)它有两个隐藏的循环(一个 in[[]] * x和一个 inmap使用list().来创建每个列表的副本)
There's also the possibility of not creating the list of lists beforehand. The other answers already cover the simple approach, but if that somehow doesn't fit your needs there are other ways. For example, you could make a function that append an empty list to the resultlist as necessary, and call that:
也有可能不事先创建列表列表。其他答案已经涵盖了简单的方法,但是如果这不符合您的需求,还有其他方法。例如,您可以创建一个函数,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)
Or you could use a collections.defaultdict(list)instead of a list:
或者你可以使用一个collections.defaultdict(list)而不是一个列表:
import collections
result = collections.defaultdict(list)
for i in range(x):
for j in someListOfElements:
result[i].append(j)
That has the benefit of using an already existing type, which is less work, but it does mean you now have a dict (indexed by integers) instead of a list, which may or may not be what you want. Or you could make a class that behaves almost like a list but appends new lists to itself instead of raising IndexError, such as:
这样做的好处是使用已经存在的类型,这减少了工作量,但这确实意味着您现在有一个 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)
回答by aaronasterling
You could write a quick generator function. This would have uses other than this particular case so I'll generalize it a little. Dig this:
您可以编写一个快速生成器函数。除了这种特殊情况外,这还有其他用途,因此我将对其进行一些概括。挖这个:
def create(n, constructor=list):
for _ in xrange(n):
yield constructor()
Then to make a list of lists,
然后制作一个列表列表,
result = list(create(10))
to make a list of empty dicts,
制作空字典列表,
result = list(create(20, dict))
and (for the sake of completeness) to make a list of empty Foos,
并且(为了完整起见)列出空的 Foos,
result = list(create(30, Foo))
Of course, you could also make a tuple of any of the above. It wouldn't be too hard to extend it to allow arguments to constructor either. I would probably have it accept a function which accepted an index and returned the arguments to be passed to the constructor.
当然,您也可以创建上述任何一个的元组。扩展它以允许构造函数的参数也不会太难。我可能会让它接受一个接受索引并返回要传递给构造函数的参数的函数。
One last thought is that, because the only requirement that we are placing on constructoris that it be a callable, you could even pass it anything that returns what you want in your list. A bound method that pulls results out of a database query for instance. It's quite a useful little three lines of code.
最后一个想法是,因为我们提出的唯一要求constructor是它是可调用的,您甚至可以将任何返回您想要的列表中的内容传递给它。例如,从数据库查询中提取结果的绑定方法。这是非常有用的三行代码。

