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?

Gill Bates
  • 11,140
  • 22
  • 64
  • 134

4 Answers4

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)
   ....:         
Ashwini Chaudhary
  • 232,417
  • 55
  • 437
  • 487
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.

Community
  • 1
  • 1
Gareth Latty
  • 82,334
  • 16
  • 175
  • 177
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
ASGM
  • 10,212
  • 29
  • 50
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 .

Community
  • 1
  • 1
Stephane Rolland
  • 37,098
  • 33
  • 115
  • 165