Reputation: 15204
I have a list
which has the following structure:
data = [[], [], ..., []] # N sub-lists
I am receiving data from a process over which I have no control in the following format:
new_entries = ['foo', 'bar', ..., 'foobar'] # guaranteed N entries
What is the best way to have the ith item of the new_entries
stored in the ith sublist of data
?
So that the result after one arrival would be:
data = [['foo'], ['bar'], ..., ['foobar']]
Is the following as good as it gets?
for i, item in enumerate(new_entries):
data[i].append(item)
Upvotes: 2
Views: 88
Reputation: 71451
If the length of data
is the same as new_entries
, then you can merely encapsulating each item in a list:
new_entries = ['foo', 'bar', ..., 'foobar']
final_entries = [[i] for i in new_entries]
To add new data at any time, you can use a class:
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']]
Upvotes: 1
Reputation: 73450
Using zip
seems a little more elegant than enumerate
, but generally there is nothing wrong with your code. For any production-level code that anybody will ever have to read or maintain, this (or yours) should be the way to go:
for lst, entry in zip(data, new_entries):
lst.append(entry)
If you feel the pathologic urge to do it in one line, you could use map
or a comprehension:
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)]
but I would strongly recommend not sacrificing readability for saving lines. In both cases the mutation of the lists in data
is more of a side effect!
And, of course, a good old list comprehension (that actually uses the result of the comprehension) can be used but does come with performance issues as the concatenation is O(M+N)
:
data = [lst + [entry] for lst, entry in zip(data, new_entries)]
Upvotes: 3