Bor*_*lik 40 python memory-management
我需要逐步填充列表或列表元组.看起来像这样的东西:
result = []
firstTime = True
for i in range(x):
for j in someListOfElements:
if firstTime:
result.append([f(j)])
else:
result[i].append(j)
Run Code Online (Sandbox Code Playgroud)
为了使它更简洁更优雅,我想我会预先分配一个空列表列表
result = createListOfEmptyLists(x)
for i in range(x):
for j in someListOfElements:
result[i].append(j)
Run Code Online (Sandbox Code Playgroud)
预分配部分对我来说并不明显.当我这样做时result = [[]] * x,我收到一个x对同一列表的引用列表,以便输出如下
result[0].append(10)
print result
Run Code Online (Sandbox Code Playgroud)
是:
[[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]]
Run Code Online (Sandbox Code Playgroud)
我可以使用loop(result = [[] for i in range(x)]),但我想知道是否存在"无循环"解决方案.
是获得我正在寻找的唯一方法
Wil*_*ill 52
result = [list(someListOfElements) for _ in xrange(x)]
Run Code Online (Sandbox Code Playgroud)
这将生成x个不同的列表,每个列表都有一个someListOfElements列表副本(该列表中的每个项目都是通过引用,但其中的列表是副本).
如果它更有意义,请考虑使用 copy.deepcopy(someListOfElements)
生成器和列表推导和事物被认为是非常pythonic.
有没有真正的方式没有的循环来创建这样一个列表的一些排序.但是,隐藏循环有多种方法,就像[[]] * x隐藏循环一样.还有的列表理解,这"隐藏"的循环中的表达式(位这是令人欣慰的还是显而易见的.)还有map(list, [[]]*x)其中有2个隐藏的循环(一个在[[]] * 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)
Run Code Online (Sandbox Code Playgroud)
或者您可以使用collections.defaultdict(list)而不是列表:
import collections
result = collections.defaultdict(list)
for i in range(x):
for j in someListOfElements:
result[i].append(j)
Run Code Online (Sandbox Code Playgroud)
这样做的好处是使用已经存在的类型,这样做的工作量较少,但它确实意味着你现在有一个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)
Run Code Online (Sandbox Code Playgroud)
你可以写一个快速生成器函数.除了这个特殊情况之外,这将有其他用途,所以我会稍微概括一下.挖这个:
def create(n, constructor=list):
for _ in xrange(n):
yield constructor()
Run Code Online (Sandbox Code Playgroud)
然后列出一个列表,
result = list(create(10))
Run Code Online (Sandbox Code Playgroud)
列出空的dicts,
result = list(create(20, dict))
Run Code Online (Sandbox Code Playgroud)
并且(为了完整起见)列出空的Foos,
result = list(create(30, Foo))
Run Code Online (Sandbox Code Playgroud)
当然,你也可以制作上述任何一个元组.扩展它以允许构造函数的参数也不会太难.我可能会接受一个接受索引的函数并返回要传递给构造函数的参数.
最后一个想法是,因为我们要求的唯一要求constructor是它是一个可调用的,你甚至可以传递它在你的列表中返回你想要的东西.例如,一种绑定方法,用于从数据库查询中提取结果.这是非常有用的三行代码.