Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python list concatenation efficiency

Tags:

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 possibilities in mind:

# 1 list_a = list_b + list_a  # 2 for item in list_b:     list_a.insert(0, item)  # 3 for item in self.list_a:     list_b.append(item) list_a = list_b  # 4 list_a[0:0] = list_b 

Thanks!

like image 573
Thorfin Avatar asked Aug 23 '12 08:08

Thorfin


People also ask

Does list concatenation create a new list?

Yes: list1 + list2 . This gives a new list that is the concatenation of list1 and list2 .

Does list concatenation create a new list Python?

You can concatenate multiple lists into one list by using the * operator. For Example, [*list1, *list2] – concatenates the items in list1 and list2 and creates a new resultant list object.

How does list concatenation work?

1. Concatenation operator (+) for List Concatenation. The '+' operator can be used to concatenate two lists. It appends one list at the end of the other list and results in a new list as output.

Is += same as extend?

To summarize: the difference between the + method and the += and extend() methods is that the former creates a new list and the latter modify an existing list object in-place.


2 Answers

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 
like image 83
Lauritz V. Thaulow Avatar answered Oct 04 '22 20:10

Lauritz V. Thaulow


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 called list_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:

class ListChain(list):     def __init__(self, *lists):         self._lists = lists      def __iter__(self):         return itertools.chain.from_iterable(self._lists)      def __len__(self):         return sum(len(l) for l in self._lists)      def append(self, item):         self._lists[-1].append(item)      def extend(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.

like image 38
lvc Avatar answered Oct 04 '22 22:10

lvc