4

This is python syntax related question... Is there more elegant and more pythonic way of doing this:

>>> test = [[1,2], [3,4,5], [1,2,3,4,5,6]]
>>> result = []
>>> for i in test: result += i
>>> result
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6]

Join multiple list (stored inside another list) to one long list?

Vyktor
  • 20,559
  • 6
  • 64
  • 96
  • @AshwiniChaudhary you're right it's a duplicate, didn't occur to me to use word `flat` when searching for similar questions. – Vyktor Apr 20 '13 at 18:03
  • 3
    There is no inherent harm to posting a duplicate, don't worry. Sometimes it's laziness on the poster's part, but in some cases it's a case of different wording, that's why duplicated don't disappear, and instead remain open as 'pointers' to the duplicated question, which means those search terms now point to an answer. – Gareth Latty Apr 20 '13 at 18:13

1 Answers1

9

Use the itertools.chain.from_iterable() classmethod:

from itertools import chain

result = list(chain.from_iterable(test))

If all you need to do is iterate over the chained lists, then don't materialize it to a list(), just loop:

for elem in chain.from_iterable(test):
    print(elem, end=' ')   # prints 1 2 3 4 5 1 2 3 4 5 6

You can also use parameter unpacking, directly on itertools.chain:

for elem in chain(*test):

But do this only with a smaller list.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Do you? I think `from_iterable` is not necessary or useful in this case. – Andrew Gorcester Apr 20 '13 at 18:04
  • @A.R.S.: In this case `*test` will do. – Martijn Pieters Apr 20 '13 at 18:04
  • Oh, never mind, I see – arshajii Apr 20 '13 at 18:04
  • 3
    `from_iterable()` makes far more sense here. Why use `*` unpacking when `from_iterable()` is designed to do the job? On a small list, there is no difference, but on a larger one, it could make a big difference. – Gareth Latty Apr 20 '13 at 18:07
  • @Lattyware: Because `test` is not a generator. Why feed the list one by one when you have it ready expanded? – Martijn Pieters Apr 20 '13 at 18:13
  • 2
    @Lattyware: Hrm, yes, with a big list it'll use a copy, you have a point ther. – Martijn Pieters Apr 20 '13 at 18:19
  • 1
    Yeah. It's not the end of the world, but it makes a lot more sense to just always use `chain.from_iterable()` over `*` unpacking - there is no real downside (slightly less nice syntax, but not horrific), and a potential gain. It also means the code is more flexible if it happens to take a generator or a large list tomorrow, which is always a possibility with a dynamic language like Python. – Gareth Latty Apr 20 '13 at 18:22