我有list
,其结构如下:
data = [[], [], ..., []] # N sub-lists
我从以下格式无法控制的流程中接收数据:
new_entries = ['foo', 'bar', ..., 'foobar'] # guaranteed N entries
new_entries
的i th 子列表中存储data
的i th 项的最佳方法是什么?吗
所以一次到达后的结果将是:
data = [['foo'], ['bar'], ..., ['foobar']]
以下内容是否合适?
for i, item in enumerate(new_entries):
data[i].append(item)
答案 0 :(得分:3)
使用zip
似乎比enumerate
更优雅,但通常您的代码没有任何问题。对于任何人必须阅读或维护的任何生产级代码,这个(或你的)应该是要走的路:
for lst, entry in zip(data, new_entries):
lst.append(entry)
如果你觉得在一行中做这种病的冲动,你可以使用map
或理解:
list(map(lambda x: x[0].append(x[1]), zip(data, new_entries))) # Py3
map(lambda (x, y): x.append(y), zip(data, new_entries)) # Py2
# or shorter, thx to Stefan Pochmann:
# Py3: any as a more space-efficient consumer than list
any(map(list.append, data, new_entries))
map(list.append, data, new_entries) # Py2
[lst.append(entry) for lst, entry in zip(data, new_entries)]
但我强烈建议不要牺牲保存线的可读性。在这两种情况下,data
中列表的突变更多的是副作用!
当然,可以使用一个很好的旧列表理解(实际上使用理解的结果),但是由于连接是O(M+N)
而出现性能问题:
data = [lst + [entry] for lst, entry in zip(data, new_entries)]
答案 1 :(得分:1)
如果data
的长度与new_entries
相同,那么您只能将每个项目封装在列表中:
new_entries = ['foo', 'bar', ..., 'foobar']
final_entries = [[i] for i in new_entries]
要随时添加新数据,您可以使用以下类:
class Stream:
def __init__(self):
pass
def __setitem__(self, name, stream):
self.__dict__[name] = map(lambda x:[x], stream) if name not in self.__dict__ else [d+[b] for d, b in zip(self.__dict__[name], stream)]
def __getitem__(self, name):
return self.__dict__[name]
def __repr__(self):
return "{}({})".format(self.__class__.__name__, ', '.join("{}:{}".format(a, str(list(b))) for a, b in self.__dict__.items()))
stream = Stream()
stream['first'] = ['foo', 'bar', 'foobar']
print(stream.first)
>>>[['foo'], ['bar'], ['foobar']]
stream['first'] = ['foobar', 'newfoo', 'anotherfoo']
print(stream.first)
>>>[['foo', 'foobar'], ['bar', 'newfoo'], ['foobar', 'anotherfoo']]