The numerous ways Python offers to concatenate sequences such as lists, strings, byte arrays etc.

Joining sequences of different types

Let’s assume we have the following data:

numbers = [1, 2]
strings = ('three', 'four')
binary = b'\x05\x06'

Our data is stored in three collections of different types (list, tuple and bytes). Now we want to join numbers, strings and binary together into a single flat list [1, 2, 'three', 'four', 5, 6].

Traditional approach

The most obvious way to do it is arguably a list comprehension:

data = [numbers, strings, binary]
joined = [item for sequence in data for item in sequence]
>>> joined
[1, 2, 'three', 'four', 5, 6]

which is equivalent to a regular nested loop:

joined = []
for sequence in data:
    for item in sequence:
        joined.append(item)

which in turn can be simplified by using the list.extend method:

joined = []
for sequence in data:
    joined.extend(sequence)    # or: joined += sequence
>>> joined
[1, 2, 'three', 'four', 5, 6]

Another interesting technique is a list literal with the * unpacking notation:

>>> [*numbers, *strings, *binary]
[1, 2, 'three', 'four', 5, 6]

but this one becomes rather impractical if we have many sequences to join.

Functional approach

Alternatively, out iterable sequences can be concatenated using itertools.chain:

from itertools import chain
>>> list(chain(*data))                 # or: [*chain(*data)]
[1, 2, 'three', 'four', 5, 6]

which is equivalent to

>>> list(chain.from_iterable(data))    # or: [*chain.from_iterable(data)]
[1, 2, 'three', 'four', 5, 6]

Joining sequences of the same type

In addition to all the solutions demonstrated above, sequences of the same type can typically be concatenated by simply summing them together. In the following scenario, we have all our data stored in lists:

numbers = [1, 2]
strings = ['three', 'four']
floats = [5.0, 6.0]

Again, we intend to join the numbers and strings into a single flat list [1, 2, 'three', 'four', 5.0, 6.0]. The first solution is obvious:

>>> numbers + strings + floats
[1, 2, 'three', 'four', 5.0, 6.0]

Functional approach

The same result can be achieved by taking advantage of some standard library functions. One possible way to sum sequences of the same type is by cumulatively adding them using the functools.reduce function:

from functools import reduce

data = [numbers, strings, floats]
>>> reduce(lambda x, y: x + y, data)
[1, 2, 'three', 'four', 5.0, 6.0]

or

>>> from operator import add
>>> reduce(add, data)
[1, 2, 'three', 'four', 5.0, 6.0]

Alternatively, the built-in function sum can be used as well:

>>> sum(data, [])
[1, 2, 'three', 'four', 5.0, 6.0]

Note: the official documentation suggests to use itertools.chain rather than sum to concatenate iterables.

Final note

All solutions shown in the first section can also be used to join sequences retrieved from iterators. For example:

>>> [*map(int, '12'), *(2**n for n in (2, 3))]
[1, 2, 4, 8]

(Technically, iterators themselves are not considered sequences as they don’t support indexing, slicing and len)