0

How do you deal with them? A stupid example: let's say we have a list like this

a = [[[1,2],[3,4]],[[5,6],[7,8]]]

and I want to print

[1,2,3,4,5,6,7,8]

The way I've come up with is the following:

print [b[t] for b in [c[w] for c in a for w in xrange(len(c))] for t in xrange(len(b))]

Which I find ugly as heck. Is there any better way to obtain the same result?

Pigna
  • 2,792
  • 5
  • 29
  • 51
  • Even without my answer below, your `xrange`s are pointless AFAICT. And even if they weren't, you should prefer the builtin `enumerate`. – o11c Jul 02 '15 at 21:42
  • @EthanFurman: I've unduped the question, since the dupe candidate you used was about a specific, highly suboptimal way of flattening lists, and it only flattens one level. It doesn't seem like an appropriate dupe for this. There probably is an appropriate dupe somewhere, but the candidates I've found so far either flatten one level or all the way until they reach non-lists or non-iterables. – user2357112 Jul 02 '15 at 21:47

4 Answers4

4
x = [d for b in a for c in b for d in c]

or using itertools.chain.from_iterable:

import itertools
flatten = itertools.chain.from_iterable
x = list(flatten(flatten(a)))
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • why import chain if you can write it in one line? Which one is better? – Pigna Jul 02 '15 at 21:48
  • @Pigna: I'd probably prefer `chain.from_iterable`. It makes it clearer that there are two levels of flattening. The list comprehension has 3 `for` clauses, but it only flattens 2 levels, which can cause confusion. – user2357112 Jul 02 '15 at 21:50
  • oh, so you are talking about readability. I've tested the two methods and the first one (0.000045 secs) is quite faster than the second (0.00020 secs). – Pigna Jul 03 '15 at 09:30
  • @Pigna: When I time it, the difference isn't nearly that bad, especially if the import and the initialization of `flatten` are outside the timing loop. – user2357112 Jul 03 '15 at 10:12
0

You want to flatten the list to get all the items. I would try itertools.chain.from_iterable to do so:

itertools.chain.from_iterable(itertools.chain.from_iterable(a)) # unpack the list twice
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70
0

Numpy works also:

print list(np.array(a).flatten())
kezzos
  • 3,023
  • 3
  • 20
  • 37
-1

Of course there's a better way:

list(itertools.chain.fromiterable(a))
o11c
  • 15,265
  • 4
  • 50
  • 75