我需要逐步填充列表或列表元组。看起来像这样:
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)]
),但我想知道是否存在“无循环”解决方案。
是获得我正在寻找的唯一方法
答案 0 :(得分:51)
result = [list(someListOfElements) for _ in xrange(x)]
这将生成x个不同的列表,每个列表都有someListOfElements
列表的副本(该列表中的每个项目都是引用,但其中的列表是副本)。
如果更有意义,请考虑使用copy.deepcopy(someListOfElements)
生成器和列表推导和事物被认为是非常 pythonic 。
答案 1 :(得分:7)
如果没有某些排序循环,就没有办法创建这样的列表。但是,隐藏循环有多种方法,就像[[]] * 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)
答案 2 :(得分:5)
您可以编写快速生成器功能。除了这个特殊情况之外,这将有其他用途,所以我会稍微概括一下。挖掘这个:
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
上的唯一要求是它是一个可调用的,你甚至可以传递任何能够在你的列表中返回你想要的东西。例如,一种绑定方法,用于从数据库查询中提取结果。这是非常有用的三行代码。
答案 3 :(得分: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']]
答案 4 :(得分:0)
请包含 runnable 示例代码,以便我们可以自行运行代码以快速查看您想要执行的操作。看起来你只想要这个:
result = []
for i in range(x):
data = []
for j in someListOfElements:
data.append(j)
# or data = [j for j in someListOfElements]
result.append(data)