The goal: working analogue of expression
{k1: v1, k2: v2 for k1, k2, v1, v2 in data}
or more particular case {k1: v, k2: v for k1, k2, v, _ in data}
that iterates through data
only 1 time (in given examples data
is iterable object of 4-tuples).
(And similar question about list comprehension, e.g. [myfunc1(v1), myfunc2(v2) for v1, v2 in data]
).
I can suppose only solution using own iterator:
def getby(iterable_data, iterable_indexes):
for indexed_data in iterable_data:
for tupl in iterable_indexes:
yield tuple(indexed_data[ind] for ind in tupl)
raise StopIteration
Example of working: list(getby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')], [(0, 1), (2, 1)]))
returns [('a', 'b'), ('c', 'b'), ('d', 'e'), ('f', 'e')]
.
But possible it is slow.
I also can suppose equivalent expression for example above in terms of itertools.chain
and itertools.groupby
:
list(chain.from_iterable(lst for lst, _ in groupby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')],
lambda lst: [(lst[0], lst[1]), (lst[2], lst[1])])))
But possible it is ugly.
ipython-based comparison of two solution: the first 1000 loops, best of 3: 20.2 ms per loop, the second 1000 loops, best of 3: 4.12 ms per loop, so the second solution really faster. But maybe is more elegant solution exist?