Reputation: 83
>>> a=["a"]*4
>>> a
['a', 'a', 'a', 'a']
>>> b=range(4)
>>> b
[0, 1, 2, 3]
>>> c = [range(4,8), range(9,13), range(14,18), range(19,23)]
>>> c
[[4, 5, 6, 7], [9, 10, 11, 12], [14, 15, 16, 17], [19, 20, 21, 22]]
>>>
>>> result = map(lambda x,y:[x,y],a,b)
>>> map(lambda x,y:x.extend(y),result,c)
>>> result = map(tuple, result)
>>> result # desired output:
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12), ('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]
>>>
>>> try_test = zip(a,b,c)
>>> try_test # NOT DESIRED: leaves me with the list within the tuples
[('a', 0, [4, 5, 6, 7]), ('a', 1, [9, 10, 11, 12]), ('a', 2, [14, 15, 16, 17]), ('a', 3, [19, 20, 21, 22])]
I was wondering whether anyone has a more succinct way to do the "result"?
Upvotes: 4
Views: 6700
Reputation: 151007
For a fully general approach to this problem, you might consider using one of the many variations on flatten
you can find here, where flatten
is a function that takes an arbitrarily nested iterable of iterables and returns a flat list of the items contained therein.
Then just map flatten
over the zipped values of a, b, c
and convert to tuple.
>>> from collections import Iterable
>>> def flatten(l):
... for i in l:
... if isinstance(i, Iterable) and not isinstance(i, basestring):
... for sub in flatten(i):
... yield sub
... else:
... yield i
...
>>> map(tuple, map(flatten, zip(a, b, c)))
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12),
('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]
Or even more succinctly, modify flatten
to accept an arbitrary argument list and return a tuple. Then all you need is map
:
>>> def flat_tuple(*args):
... return tuple(flatten(args))
...
>>> map(flat_tuple, a, b, c)
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12),
('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]
If this is a one-off problem, the above approach is probably more trouble than it's worth. But if you've already defined flatten
for other purposes, or if you're doing this frequently, the above could save you a lot of trouble!
Otherwise, just for the fun of it, here's a variation on nneonneo's answer that I like:
>>> [x + tuple(y) for x, y in zip(zip(a, b), c)]
[('a', 0, 4, 5, 6, 7), ('a', 1, 9, 10, 11, 12),
('a', 2, 14, 15, 16, 17), ('a', 3, 19, 20, 21, 22)]
Upvotes: 2
Reputation: 609
For this very case: (if succinct == short)
q = lambda x : tuple(range(x,x+4))
res = [ ('a', num) + q(4*(num+1)+num) for num in xrange(4) ]
Upvotes: -2
Reputation: 179442
You could try something like this:
result = [tuple([ai, bi] + ci) for ai, bi, ci in zip(a, b, c)]
Upvotes: 6