3

I have something like this:

[e for e in ([n for n in xrange(random.randrange(1, 5))] for x in xrange(10))]

It produces:

[[0, 1, 2, 3], [0, 1, 2], [0], [0], [0, 1], [0], [0, 1], [0, 1, 2, 3], [0, 1, 2], [0, 1, 2]]

And I need the same but in flat structure.

For now I use something like:

l = []
[l.extend(e) for e in ([n for n in xrange(random.randrange(1, 5))] for x in xrange(10))]

But is there something less obsucre to achieve this 'unpacking' of arbitrary length list inside comprehension?

asked Apr 7, 2013 at 13:33
1

4 Answers 4

7

Use this list comprehension:

In [8]: [y for x in xrange(10) for y in xrange(random.randrange(1, 5))]
Out[8]: [0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 3, 0, 0, 1, 0]

The above list comprehension is equivalent to this(but LC are much faster):

In [9]: lis=[]
In [10]: for x in xrange(10):
 ....: for y in xrange(random.randrange(1, 5)):
 ....: lis.append(y)
 ....: 
answered Apr 7, 2013 at 13:38
Sign up to request clarification or add additional context in comments.

5 Comments

+1 - The best option here is to make it the way you want, not flatten it after.
+1 I didn't know whe could nest for loops into list comprehension
xrange and random is just for illustration! My case requires that elems that pops from data srouce is arbitrary length lists
@GillBates for y in xrange(random.randrange(1, 5)) iterates over that arbitrary lenght list to return a flattened list.
Iterates and generates it, in my case of course Im not generating data inside list comprehension
3

The best way to flatten any iterable in a generic situation is itertools.chain.from_iterable():

>>> import random
>>> from itertools import chain
>>> x = [e for e in ([n for n in xrange(random.randrange(1, 5))] 
... for x in xrange(10))]
>>> list(chain.from_iterable(x))
[0, 0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 0, 1, 2, 3, 0, 1, 0, 1, 0, 0, 1, 2]

This said, it's preferable to avoid the extra work in this case by just making it flat to begin with.

answered Apr 7, 2013 at 13:38

Comments

3

You can use numpy flatten():

import numpy as np
l = [e for e in ([n for n in xrange(random.randrange(1, 5))] for x in xrange(10))]
a = np.asarray(l)
l = list(a.flatten(l))
print l
answered Apr 7, 2013 at 13:38

Comments

0
import itertools
l = [e for e in ([n for n in xrange(random.randrange(1, 5))] for x in xrange(10))]
result = list(itertools.chain(*l))

and then print result gives:

[0,1,2,3,0,1,2,0...]

the use of the * in chain(*l) is inspired from this question join list of lists in python .

answered Apr 7, 2013 at 13:45

1 Comment

This is slower than itertools.chain.from_iterable() that was designed to do this more efficiently.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.