Skip to content Skip to sidebar Skip to footer

Python List Concatenation Efficiency

What is the most efficient way to concatenate two lists list_a and list_b when: list_b items have to be placed before list_a items the result must be placed in list_a I have 4

Solution 1:

Here's a graph of how the timings used in the answer of BigYellowCactus develop as the length of the lists increase. The vertical axis is the time required to initialize both lists and insert one in front of the other, in usec. The horizontal axis is the number of items in the lists.

Asymptotic behaviour of the possibilities

t1:

list_a = list_b + list_a

t2:

for item in list_b:
    list_a.insert(0, item)

t3:

for item in list_a:
    list_b.append(item)
list_a = list_b

t4:

list_a[0:0] = list_b

Solution 2:

Given that

list_a = list_b + list_a

works for your purposes, it follows that you don't actually need the list_a object itself to store all the data in list_a - you just need it calledlist_a (ie, you don't have, or don't care about, any other variables you have floating around that might refer to that same list).

If you also happen not to care about it being exactly a list, but only about it being iterable, then you can use itertools.chain:

list_a = itertools.chain(list_b, list_a)

If you do care about some list things, you could construct a similar type of thing to chain that behaves like a list - something like:

classListChain(list):
    def__init__(self, *lists):
        self._lists = lists

    def__iter__(self):
        return itertools.chain.from_iterable(self._lists)

    def__len__(self):
        returnsum(len(l) for l in self._lists)

    defappend(self, item):
        self._lists[-1].append(item)

    defextend(self, iterable):
        self._lists.append(list(iterable))

    def__getitem__(self, item):
       for l in self._lists:
           if item < len(l):
              return l[item]
           item -= len(l)
       else:
          raise IndexError

etc. This would take a lot of effort (possibly more than its worth) for this to work in all cases - eg, handling slices and negative indexes comes to mind. But for very simple cases, this approach can avoid a lot of copying list contents around.

Solution 3:

You can assign list_b to a slice, which happens to be empty but at the start of list_a:

list_a[0:0] = list_b

This is the fastest way to insert a list into another list, at any position.

Solution 4:

try this:

list_a[0:0] = list_b

Solution 5:

Why not just timeit?

import timeit

create_data = """\
list_a = range(10)
list_b = range(10)
"""

t1 = timeit.Timer(stmt=create_data + """\
list_a = list_b + list_a
""")

t2 = timeit.Timer(create_data + """\
for item in list_b:
    list_a.insert(0, item)
""")

t3 = timeit.Timer(create_data + """\
for item in list_a:
    list_b.append(item)
list_a = list_b
""")

t4 = timeit.Timer(create_data + """\
list_a[0:0] = list_b
""")

for i, t inenumerate([t1,t2,t3,t4]):
    print i, "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

Result:

0 0.73 usec/pass 1 2.79 usec/pass 2 1.66 usec/pass 3 0.77 usec/pass

Post a Comment for "Python List Concatenation Efficiency"