Reputation: 2569
I'd like to know an elegant, Pythonic way to iterate over a list of lists (or dict of lists) in parallel in Python 3. The number of lists is not known until runtime, so I believe I cannot simply supply them as arguments to the zip()
function.
For example, given the following data structure:
var = [['x1' ,'x2' ,'x3'], ['y1', 'y2', 'y3'], ['z1', 'z2', 'z3'], …]
I would like to be able to access the following values on each iteration:
x1,y1,z1
followed by x2,y2,z2
followed by x3,y3,z3
and so on.
Presumably I could achieve this using list indexes directly, or by using itertools.chain, but I'm looking for a more elegant approach using generators or otherwise.
Upvotes: 1
Views: 860
Reputation: 56714
zip(*var)
will automatically unpack your list of lists.
So, for example:
var = [['x1' ,'x2' ,'x3'], ['y1', 'y2', 'y3'], ['z1', 'z2', 'z3'], ['w1', 'w2', 'w3']]
for ltrs in zip(*var):
print(", ".join(ltrs))
results in
x1, y1, z1, w1
x2, y2, z2, w2
x3, y3, z3, w3
Edit: per comments below, he wants to use the items from a dictionary,
var = {
'id_172': ['x1', 'x2', 'x3'],
'id_182': ['y1', 'y2', 'y3'],
'id_197': ['z1', 'z2', 'z3']
}
I assume we are using the values with the keys in sorted order:
keys = sorted(var.keys())
for ltrs in zip(*(var[k] for k in keys)):
print(", ".join(ltrs))
which gives
x1, y1, z1
x2, y2, z2
x3, y3, z3
Warning: do note that this sorts the keys in lexocographic order (ie string alphabetical order), so for example "id_93" comes after "id_101". If your labels need to be sorted in numeric order you will need to use a custom key function, something like
keys = sorted(var.keys(), key=lambda k: int(k[3:]))
Upvotes: 8
Reputation: 239683
If you look at the input and output data carefully, you are actually transposing a two dimensional array. That can be done easily with Python's builtin zip
function, like this
var = [['x1' ,'x2' ,'x3'], ['y1', 'y2', 'y3'], ['z1', 'z2', 'z3']]
print list(zip(*var))
# [('x1', 'y1', 'z1'), ('x2', 'y2', 'z2'), ('x3', 'y3', 'z3')]
You can iterate over it, like this
for x, y, z in zip(*var):
print x, y, z
Output
x1 y1 z1
x2 y2 z2
x3 y3 z3
Upvotes: 2