Python weave lists - python

I want to "weave" two numberrows together.
Example:
x = [1,2,3]
y = [4,5,6]
result = [1,4,2,5,3,6]
This is my function, I can't find out why it doesn't work:
def weave(list1,list2):
lijst = []
i = 0
for i <= len(list1):
lijst += [list1[i]]
lijst += [list2[i]]
i + 1

You can use the chain function from itertools module to interleave two lists:
x = [1,2,3]
y = [4,5,6]
from itertools import chain
list(chain.from_iterable(zip(x, y)))
# [1, 4, 2, 5, 3, 6]

Python's for-loops aren't like other languages where you can have a conditional. You need to use a while loop instead or alter your for-loop:
def weave(list1,list2):
lijst = []
i = 0
while i < len(list1):
lijst.append(list1[i])
lijst.append(list2[i])
i += 1
return lijst
I've altered your code in a variety of ways:
Use a while loop if you have a condition you want to loop through
You want the conditional to be less than the length, not less than or equal to. This is because indexing starts at 0, and if you do <=, then it will try to do list1[3] which is out of bounds.
Use list.append to add items to list
You forgot the = in i += 1
Finally, don't forget to return the list!
You could also use zip():
>>> [a for b in zip(x, y) for a in b]
[1, 4, 2, 5, 3, 6]

You can also weave lists by defining the even and odd half-lists of the result list.
x = [1,2,3]
y = [4,5,6]
z = numpy.empty(len(x)+len(y))
z[::2],z[1::2]=x,y
result=z.tolist()

You need to append list item at every iteration so use list.append and in python you don't need to initialise i =0.
try this:-
>>> a = [1,2 ,3]
>>> b = [4, 5, 6]
>>> list(chain.from_iterable(zip(a, b)))
[1, 4, 2, 5, 3, 6]

You can play with this script:
reduce(lambda a, b: a+b, zip([1, 2, 3], [4, 5, 6]), ())
Notes:
zip will make pairs, add will join them;
you can use operator.add instead of lambda;
itertools.izip can be used if lengths of lists are different.

>>> x = [1,2,3]
>>> y = [4,5,6]
>>> z=[]
>>> for i,j in zip(x,y):
... z.extend([i,j])
...
>>> z
[1, 4, 2, 5, 3, 6]

I needed this, but with an arbitrary number of lists of potentially different lengths, which some of the other more elegant answers do not offer. Here is a simple implementation with no dependencies:
def weave_lists(list_of_lists):
max_index = max([len(sublist) for sublist in list_of_lists])
weaved_list = []
for sublist_index in range(max_index):
for sublist in list_of_lists:
if len(sublist) > sublist_index:
weaved_list.append(sublist[sublist_index])
return weaved_list
print(weave_lists([[1,2], [3,4,5], [6,7,8,9]]))
# [1, 3, 6, 2, 4, 7, 5, 8, 9]

x = [1,2,3]
y = [4,5,6]
As mentioned by others (and is the clearest as well as the way I'd do it since it since its the most understandable given the semantics of chain), You can do this by using itertools:
from itertools import chain
list(chain.from_iterable(zip(x, y)))
[1, 4, 2, 5, 3, 6]
However you could also use tuple summing up (concatenation) by:
list(sum(zip(x,y), ()))
[1, 4, 2, 5, 3, 6]

Related

Combining two lists with different lengths to a single list [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
How do I concatenate two lists in Python?
Example:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
Expected outcome:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
Use the + operator to combine the lists:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
joinedlist = listone + listtwo
Output:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
Python >= 3.5 alternative: [*l1, *l2]
Another alternative has been introduced via the acceptance of PEP 448 which deserves mentioning.
The PEP, titled Additional Unpacking Generalizations, generally reduced some syntactic restrictions when using the starred * expression in Python; with it, joining two lists (applies to any iterable) can now also be done with:
>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> joined_list = [*l1, *l2] # unpack both iterables in a list literal
>>> print(joined_list)
[1, 2, 3, 4, 5, 6]
This functionality was defined for Python 3.5, but it hasn't been backported to previous versions in the 3.x family. In unsupported versions a SyntaxError is going to be raised.
As with the other approaches, this too creates as shallow copy of the elements in the corresponding lists.
The upside to this approach is that you really don't need lists in order to perform it; anything that is iterable will do. As stated in the PEP:
This is also useful as a more readable way of summing iterables into a
list, such as my_list + list(my_tuple) + list(my_range) which is now
equivalent to just [*my_list, *my_tuple, *my_range].
So while addition with + would raise a TypeError due to type mismatch:
l = [1, 2, 3]
r = range(4, 7)
res = l + r
The following won't:
res = [*l, *r]
because it will first unpack the contents of the iterables and then simply create a list from the contents.
It's also possible to create a generator that simply iterates over the items in both lists using itertools.chain(). This allows you to chain lists (or any iterable) together for processing without copying the items to a new list:
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
You could also use the list.extend() method in order to add a list to the end of another one:
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
If you want to keep the original list intact, you can create a new list object, and extend both lists to it:
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
How do I concatenate two lists in Python?
As of 3.9, these are the most popular stdlib methods for concatenating two (or more) lists in Python.
Version Restrictions
In-Place?
Generalize to N lists?
a+b
-
No
sum([a, b, c], [])1
list(chain(a,b))2
>=2.3
No
list(chain(a, b, c))
[*a, *b]3
>=3.5
No
[*a, *b, *c]
a += b
-
Yes
No
a.extend(b)
-
Yes
No
Footnotes
This is a slick solution because of its succinctness. But sum performs concatenation in a pairwise fashion, which means this is a
quadratic operation as memory has to be allocated for each step. DO
NOT USE if your lists are large.
See chain
and
chain.from_iterable
from the docs. You will need to from itertools import chain first.
Concatenation is linear in memory, so this is the best in terms of
performance and version compatibility. chain.from_iterable was introduced in 2.6.
This method uses Additional Unpacking Generalizations (PEP 448), but cannot
generalize to N lists unless you manually unpack each one yourself.
a += b and a.extend(b) are more or less equivalent for all practical purposes. += when called on a list will internally call
list.__iadd__, which extends the first list by the second.
Performance
2-List Concatenation1
There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.
N-List Concatenation
Plots have been generated using the perfplot module. Code, for your reference.
1. The iadd (+=) and extend methods operate in-place, so a copy has to be generated each time before testing. To keep things fair, all methods have a pre-copy step for the left-hand list which can be ignored.
Comments on Other Solutions
DO NOT USE THE DUNDER METHOD list.__add__ directly in any way, shape or form. In fact, stay clear of dunder methods, and use the operators and operator functions like they were designed for. Python has careful semantics baked into these which are more complicated than just calling the dunder directly. Here is an example. So, to summarise, a.__add__(b) => BAD; a + b => GOOD.
Some answers here offer reduce(operator.add, [a, b]) for pairwise concatenation -- this is the same as sum([a, b], []) only more wordy.
Any method that uses set will drop duplicates and lose ordering. Use with caution.
for i in b: a.append(i) is more wordy, and slower than a.extend(b), which is single function call and more idiomatic. append is slower because of the semantics with which memory is allocated and grown for lists. See here for a similar discussion.
heapq.merge will work, but its use case is for merging sorted lists in linear time. Using it in any other situation is an anti-pattern.
yielding list elements from a function is an acceptable method, but chain does this faster and better (it has a code path in C, so it is fast).
operator.add(a, b) is an acceptable functional equivalent to a + b. It's use cases are mainly for dynamic method dispatch. Otherwise, prefer a + b which is shorter and more readable, in my opinion. YMMV.
You can use sets to obtain merged list of unique values
mergedlist = list(set(listone + listtwo))
This is quite simple, and I think it was even shown in the tutorial:
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
This question directly asks about joining two lists. However it's pretty high in search even when you are looking for a way of joining many lists (including the case when you joining zero lists).
I think the best option is to use list comprehensions:
>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> [x for xs in a for x in xs]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
You can create generators as well:
>>> map(str, (x for xs in a for x in xs))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
Old Answer
Consider this more generic approach:
a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])
Will output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Note, this also works correctly when a is [] or [[1,2,3]].
However, this can be done more efficiently with itertools:
a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))
If you don't need a list, but just an iterable, omit list().
Update
Alternative suggested by Patrick Collins in the comments could also work for you:
sum(a, [])
You could simply use the + or += operator as follows:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
Or:
c = []
a = [1, 2, 3]
b = [4, 5, 6]
c += (a + b)
Also, if you want the values in the merged list to be unique you can do:
c = list(set(a + b))
It's worth noting that the itertools.chain function accepts variable number of arguments:
>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']
If an iterable (tuple, list, generator, etc.) is the input, the from_iterable class method may be used:
>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']
For cases with a low number of lists you can simply add the lists together or use in-place unpacking (available in Python-3.5+):
In [1]: listone = [1, 2, 3]
...: listtwo = [4, 5, 6]
In [2]: listone + listtwo
Out[2]: [1, 2, 3, 4, 5, 6]
In [3]: [*listone, *listtwo]
Out[3]: [1, 2, 3, 4, 5, 6]
As a more general way for cases with more number of lists you can use chain.from_iterable()1 function from itertools module. Also, based on this answer this function is the best; or at least a very good way for flatting a nested list as well.
>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1. Note that `chain.from_iterable()` is available in Python 2.6 and later. In other versions, use `chain(*l)`.
With Python 3.3+ you can use yield from:
listone = [1,2,3]
listtwo = [4,5,6]
def merge(l1, l2):
yield from l1
yield from l2
>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]
Or, if you want to support an arbitrary number of iterators:
def merge(*iters):
for it in iters:
yield from it
>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]
If you want to merge the two lists in sorted form, you can use the merge function from the heapq library.
from heapq import merge
a = [1, 2, 4]
b = [2, 4, 6, 7]
print list(merge(a, b))
If you can't use the plus operator (+), you can use the operator import:
import operator
listone = [1,2,3]
listtwo = [4,5,6]
result = operator.add(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
Alternatively, you could also use the __add__ dunder function:
listone = [1,2,3]
listtwo = [4,5,6]
result = list.__add__(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
If you need to merge two ordered lists with complicated sorting rules, you might have to roll it yourself like in the following code (using a simple sorting rule for readability :-) ).
list1 = [1,2,5]
list2 = [2,3,4]
newlist = []
while list1 and list2:
if list1[0] == list2[0]:
newlist.append(list1.pop(0))
list2.pop(0)
elif list1[0] < list2[0]:
newlist.append(list1.pop(0))
else:
newlist.append(list2.pop(0))
if list1:
newlist.extend(list1)
if list2:
newlist.extend(list2)
assert(newlist == [1, 2, 3, 4, 5])
If you are using NumPy, you can concatenate two arrays of compatible dimensions with this command:
numpy.concatenate([a,b])
Use a simple list comprehension:
joined_list = [item for list_ in [list_one, list_two] for item in list_]
It has all the advantages of the newest approach of using Additional Unpacking Generalizations - i.e. you can concatenate an arbitrary number of different iterables (for example, lists, tuples, ranges, and generators) that way - and it's not limited to Python 3.5 or later.
Another way:
>>> listone = [1, 2, 3]
>>> listtwo = [4, 5, 6]
>>> joinedlist = [*listone, *listtwo]
>>> joinedlist
[1, 2, 3, 4, 5, 6]
>>>
list(set(listone) | set(listtwo))
The above code does not preserve order and removes duplicates from each list (but not from the concatenated list).
As already pointed out by many, itertools.chain() is the way to go if one needs to apply exactly the same treatment to both lists. In my case, I had a label and a flag which were different from one list to the other, so I needed something slightly more complex. As it turns out, behind the scenes itertools.chain() simply does the following:
for it in iterables:
for element in it:
yield element
(see https://docs.python.org/2/library/itertools.html), so I took inspiration from here and wrote something along these lines:
for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
print header + ':'
for path in iterable:
[...]
command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
print >> SCRIPT , command, flag, srcPath, mergedDirPath
[...]
The main points to understand here are that lists are just a special case of iterable, which are objects like any other; and that for ... in loops in python can work with tuple variables, so it is simple to loop on multiple variables at the same time.
You could use the append() method defined on list objects:
mergedlist =[]
for elem in listone:
mergedlist.append(elem)
for elem in listtwo:
mergedlist.append(elem)
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)
Output
>>> [1, 2, 3, 4, 5, 6]
In the above code, the "+" operator is used to concatenate the two lists into a single list.
Another solution
a = [1, 2, 3]
b = [4, 5, 6]
c = [] # Empty list in which we are going to append the values of list (a) and (b)
for i in a:
c.append(i)
for j in b:
c.append(j)
print(c)
Output
>>> [1, 2, 3, 4, 5, 6]
All the possible ways to join lists that I could find
import itertools
A = [1,3,5,7,9] + [2,4,6,8,10]
B = [1,3,5,7,9]
B.append([2,4,6,8,10])
C = [1,3,5,7,9]
C.extend([2,4,6,8,10])
D = list(zip([1,3,5,7,9],[2,4,6,8,10]))
E = [1,3,5,7,9]+[2,4,6,8,10]
F = list(set([1,3,5,7,9] + [2,4,6,8,10]))
G = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
G.append(a)
print("A: " + str(A))
print("B: " + str(B))
print("C: " + str(C))
print("D: " + str(D))
print("E: " + str(E))
print("F: " + str(F))
print("G: " + str(G))
Output
A: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
B: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
C: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
D: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
G: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
I recommend three methods to concatenate the list, but the first method is most recommended,
# Easiest and least complexity method <= recommended
listone = [1, 2, 3]
listtwo = [4, 5, 6]
newlist = listone + listtwo
print(newlist)
# Second-easiest method
newlist = listone.copy()
newlist.extend(listtwo)
print(newlist)
In the second method, I assign newlist to a copy of the listone, because I don't want to change listone.
# Third method
newlist = listone.copy()
for j in listtwo:
newlist.append(j)
print(newlist)
This is not a good way to concatenate lists because we are using a for loop to concatenate the lists. So time complexity is much higher than with the other two methods.
The most common method used to concatenate lists are the plus operator and the built-in method append, for example:
list = [1,2]
list = list + [3]
# list = [1,2,3]
list.append(3)
# list = [1,2,3]
list.append([3,4])
# list = [1,2,[3,4]]
For most of the cases, this will work, but the append function will not extend a list if one was added. Because that is not expected, you can use another method called extend. It should work with structures:
list = [1,2]
list.extend([3,4])
# list = [1,2,3,4]
A really concise way to combine a list of lists is
list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
reduce(list.__add__, list_of_lists)
which gives us
[1, 2, 3, 4, 5, 6, 7, 8, 9]
So there are two easy ways.
Using +: It creates a new list from provided lists
Example:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
Using extend: It appends new list to existing list. That means it does not create a separate list.
Example:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: %timeit a.extend(b)
10000000 loops, best of 3: 91.1 ns per loop
Thus we see that out of two of most popular methods, extend is efficient.
You could also just use sum.
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> sum([a, b], [])
[1, 2, 3, 4, 5, 6]
>>>
This works for any length and any element type of list:
>>> a = ['a', 'b', 'c', 'd']
>>> b = [1, 2, 3, 4]
>>> c = [1, 2]
>>> sum([a, b, c], [])
['a', 'b', 'c', 'd', 1, 2, 3, 4, 1, 2]
>>>
The reason I add [], is because the start argument is set to 0 by default, so it loops through the list and adds to start, but 0 + [1, 2, 3] would give an error, so if we set the start to []. It would add to [], and [] + [1, 2, 3] would work as expected.
I assume you want one of the two methods:
Keep duplicate elements
It is very easy. Just concatenate like a string:
def concat_list(l1,l2):
l3 = l1+l2
return l3
Next, if you want to eliminate duplicate elements
def concat_list(l1,l2):
l3 = []
for i in [l1,l2]:
for j in i:
if j not in l3:
# Check if element exists in final list, if no then add element to list
l3.append(j)
return l3
The solutions provided are for a single list. In case there are lists within a list and the merging of corresponding lists is required, the "+" operation through a for loop does the work.
a = [[1,2,3], [4,5,6]]
b = [[0,1,2], [7,8,9]]
for i in range(len(a)):
cc.append(a[i] + b[i])
Output: [[1, 2, 3, 0, 1, 2], [4, 5, 6, 7, 8, 9]]

Is there a way to split a tuple containing three lists into its individual elements [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
How do I concatenate two lists in Python?
Example:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
Expected outcome:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
Use the + operator to combine the lists:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
joinedlist = listone + listtwo
Output:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
Python >= 3.5 alternative: [*l1, *l2]
Another alternative has been introduced via the acceptance of PEP 448 which deserves mentioning.
The PEP, titled Additional Unpacking Generalizations, generally reduced some syntactic restrictions when using the starred * expression in Python; with it, joining two lists (applies to any iterable) can now also be done with:
>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> joined_list = [*l1, *l2] # unpack both iterables in a list literal
>>> print(joined_list)
[1, 2, 3, 4, 5, 6]
This functionality was defined for Python 3.5, but it hasn't been backported to previous versions in the 3.x family. In unsupported versions a SyntaxError is going to be raised.
As with the other approaches, this too creates as shallow copy of the elements in the corresponding lists.
The upside to this approach is that you really don't need lists in order to perform it; anything that is iterable will do. As stated in the PEP:
This is also useful as a more readable way of summing iterables into a
list, such as my_list + list(my_tuple) + list(my_range) which is now
equivalent to just [*my_list, *my_tuple, *my_range].
So while addition with + would raise a TypeError due to type mismatch:
l = [1, 2, 3]
r = range(4, 7)
res = l + r
The following won't:
res = [*l, *r]
because it will first unpack the contents of the iterables and then simply create a list from the contents.
It's also possible to create a generator that simply iterates over the items in both lists using itertools.chain(). This allows you to chain lists (or any iterable) together for processing without copying the items to a new list:
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
You could also use the list.extend() method in order to add a list to the end of another one:
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
If you want to keep the original list intact, you can create a new list object, and extend both lists to it:
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
How do I concatenate two lists in Python?
As of 3.9, these are the most popular stdlib methods for concatenating two (or more) lists in Python.
Version Restrictions
In-Place?
Generalize to N lists?
a+b
-
No
sum([a, b, c], [])1
list(chain(a,b))2
>=2.3
No
list(chain(a, b, c))
[*a, *b]3
>=3.5
No
[*a, *b, *c]
a += b
-
Yes
No
a.extend(b)
-
Yes
No
Footnotes
This is a slick solution because of its succinctness. But sum performs concatenation in a pairwise fashion, which means this is a
quadratic operation as memory has to be allocated for each step. DO
NOT USE if your lists are large.
See chain
and
chain.from_iterable
from the docs. You will need to from itertools import chain first.
Concatenation is linear in memory, so this is the best in terms of
performance and version compatibility. chain.from_iterable was introduced in 2.6.
This method uses Additional Unpacking Generalizations (PEP 448), but cannot
generalize to N lists unless you manually unpack each one yourself.
a += b and a.extend(b) are more or less equivalent for all practical purposes. += when called on a list will internally call
list.__iadd__, which extends the first list by the second.
Performance
2-List Concatenation1
There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.
N-List Concatenation
Plots have been generated using the perfplot module. Code, for your reference.
1. The iadd (+=) and extend methods operate in-place, so a copy has to be generated each time before testing. To keep things fair, all methods have a pre-copy step for the left-hand list which can be ignored.
Comments on Other Solutions
DO NOT USE THE DUNDER METHOD list.__add__ directly in any way, shape or form. In fact, stay clear of dunder methods, and use the operators and operator functions like they were designed for. Python has careful semantics baked into these which are more complicated than just calling the dunder directly. Here is an example. So, to summarise, a.__add__(b) => BAD; a + b => GOOD.
Some answers here offer reduce(operator.add, [a, b]) for pairwise concatenation -- this is the same as sum([a, b], []) only more wordy.
Any method that uses set will drop duplicates and lose ordering. Use with caution.
for i in b: a.append(i) is more wordy, and slower than a.extend(b), which is single function call and more idiomatic. append is slower because of the semantics with which memory is allocated and grown for lists. See here for a similar discussion.
heapq.merge will work, but its use case is for merging sorted lists in linear time. Using it in any other situation is an anti-pattern.
yielding list elements from a function is an acceptable method, but chain does this faster and better (it has a code path in C, so it is fast).
operator.add(a, b) is an acceptable functional equivalent to a + b. It's use cases are mainly for dynamic method dispatch. Otherwise, prefer a + b which is shorter and more readable, in my opinion. YMMV.
You can use sets to obtain merged list of unique values
mergedlist = list(set(listone + listtwo))
This is quite simple, and I think it was even shown in the tutorial:
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
This question directly asks about joining two lists. However it's pretty high in search even when you are looking for a way of joining many lists (including the case when you joining zero lists).
I think the best option is to use list comprehensions:
>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> [x for xs in a for x in xs]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
You can create generators as well:
>>> map(str, (x for xs in a for x in xs))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
Old Answer
Consider this more generic approach:
a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])
Will output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Note, this also works correctly when a is [] or [[1,2,3]].
However, this can be done more efficiently with itertools:
a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))
If you don't need a list, but just an iterable, omit list().
Update
Alternative suggested by Patrick Collins in the comments could also work for you:
sum(a, [])
You could simply use the + or += operator as follows:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
Or:
c = []
a = [1, 2, 3]
b = [4, 5, 6]
c += (a + b)
Also, if you want the values in the merged list to be unique you can do:
c = list(set(a + b))
It's worth noting that the itertools.chain function accepts variable number of arguments:
>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']
If an iterable (tuple, list, generator, etc.) is the input, the from_iterable class method may be used:
>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']
For cases with a low number of lists you can simply add the lists together or use in-place unpacking (available in Python-3.5+):
In [1]: listone = [1, 2, 3]
...: listtwo = [4, 5, 6]
In [2]: listone + listtwo
Out[2]: [1, 2, 3, 4, 5, 6]
In [3]: [*listone, *listtwo]
Out[3]: [1, 2, 3, 4, 5, 6]
As a more general way for cases with more number of lists you can use chain.from_iterable()1 function from itertools module. Also, based on this answer this function is the best; or at least a very good way for flatting a nested list as well.
>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1. Note that `chain.from_iterable()` is available in Python 2.6 and later. In other versions, use `chain(*l)`.
With Python 3.3+ you can use yield from:
listone = [1,2,3]
listtwo = [4,5,6]
def merge(l1, l2):
yield from l1
yield from l2
>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]
Or, if you want to support an arbitrary number of iterators:
def merge(*iters):
for it in iters:
yield from it
>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]
If you want to merge the two lists in sorted form, you can use the merge function from the heapq library.
from heapq import merge
a = [1, 2, 4]
b = [2, 4, 6, 7]
print list(merge(a, b))
If you can't use the plus operator (+), you can use the operator import:
import operator
listone = [1,2,3]
listtwo = [4,5,6]
result = operator.add(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
Alternatively, you could also use the __add__ dunder function:
listone = [1,2,3]
listtwo = [4,5,6]
result = list.__add__(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
If you need to merge two ordered lists with complicated sorting rules, you might have to roll it yourself like in the following code (using a simple sorting rule for readability :-) ).
list1 = [1,2,5]
list2 = [2,3,4]
newlist = []
while list1 and list2:
if list1[0] == list2[0]:
newlist.append(list1.pop(0))
list2.pop(0)
elif list1[0] < list2[0]:
newlist.append(list1.pop(0))
else:
newlist.append(list2.pop(0))
if list1:
newlist.extend(list1)
if list2:
newlist.extend(list2)
assert(newlist == [1, 2, 3, 4, 5])
If you are using NumPy, you can concatenate two arrays of compatible dimensions with this command:
numpy.concatenate([a,b])
Use a simple list comprehension:
joined_list = [item for list_ in [list_one, list_two] for item in list_]
It has all the advantages of the newest approach of using Additional Unpacking Generalizations - i.e. you can concatenate an arbitrary number of different iterables (for example, lists, tuples, ranges, and generators) that way - and it's not limited to Python 3.5 or later.
Another way:
>>> listone = [1, 2, 3]
>>> listtwo = [4, 5, 6]
>>> joinedlist = [*listone, *listtwo]
>>> joinedlist
[1, 2, 3, 4, 5, 6]
>>>
list(set(listone) | set(listtwo))
The above code does not preserve order and removes duplicates from each list (but not from the concatenated list).
As already pointed out by many, itertools.chain() is the way to go if one needs to apply exactly the same treatment to both lists. In my case, I had a label and a flag which were different from one list to the other, so I needed something slightly more complex. As it turns out, behind the scenes itertools.chain() simply does the following:
for it in iterables:
for element in it:
yield element
(see https://docs.python.org/2/library/itertools.html), so I took inspiration from here and wrote something along these lines:
for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
print header + ':'
for path in iterable:
[...]
command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
print >> SCRIPT , command, flag, srcPath, mergedDirPath
[...]
The main points to understand here are that lists are just a special case of iterable, which are objects like any other; and that for ... in loops in python can work with tuple variables, so it is simple to loop on multiple variables at the same time.
You could use the append() method defined on list objects:
mergedlist =[]
for elem in listone:
mergedlist.append(elem)
for elem in listtwo:
mergedlist.append(elem)
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)
Output
>>> [1, 2, 3, 4, 5, 6]
In the above code, the "+" operator is used to concatenate the two lists into a single list.
Another solution
a = [1, 2, 3]
b = [4, 5, 6]
c = [] # Empty list in which we are going to append the values of list (a) and (b)
for i in a:
c.append(i)
for j in b:
c.append(j)
print(c)
Output
>>> [1, 2, 3, 4, 5, 6]
All the possible ways to join lists that I could find
import itertools
A = [1,3,5,7,9] + [2,4,6,8,10]
B = [1,3,5,7,9]
B.append([2,4,6,8,10])
C = [1,3,5,7,9]
C.extend([2,4,6,8,10])
D = list(zip([1,3,5,7,9],[2,4,6,8,10]))
E = [1,3,5,7,9]+[2,4,6,8,10]
F = list(set([1,3,5,7,9] + [2,4,6,8,10]))
G = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
G.append(a)
print("A: " + str(A))
print("B: " + str(B))
print("C: " + str(C))
print("D: " + str(D))
print("E: " + str(E))
print("F: " + str(F))
print("G: " + str(G))
Output
A: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
B: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
C: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
D: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
G: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
I recommend three methods to concatenate the list, but the first method is most recommended,
# Easiest and least complexity method <= recommended
listone = [1, 2, 3]
listtwo = [4, 5, 6]
newlist = listone + listtwo
print(newlist)
# Second-easiest method
newlist = listone.copy()
newlist.extend(listtwo)
print(newlist)
In the second method, I assign newlist to a copy of the listone, because I don't want to change listone.
# Third method
newlist = listone.copy()
for j in listtwo:
newlist.append(j)
print(newlist)
This is not a good way to concatenate lists because we are using a for loop to concatenate the lists. So time complexity is much higher than with the other two methods.
The most common method used to concatenate lists are the plus operator and the built-in method append, for example:
list = [1,2]
list = list + [3]
# list = [1,2,3]
list.append(3)
# list = [1,2,3]
list.append([3,4])
# list = [1,2,[3,4]]
For most of the cases, this will work, but the append function will not extend a list if one was added. Because that is not expected, you can use another method called extend. It should work with structures:
list = [1,2]
list.extend([3,4])
# list = [1,2,3,4]
A really concise way to combine a list of lists is
list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
reduce(list.__add__, list_of_lists)
which gives us
[1, 2, 3, 4, 5, 6, 7, 8, 9]
So there are two easy ways.
Using +: It creates a new list from provided lists
Example:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
Using extend: It appends new list to existing list. That means it does not create a separate list.
Example:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: %timeit a.extend(b)
10000000 loops, best of 3: 91.1 ns per loop
Thus we see that out of two of most popular methods, extend is efficient.
You could also just use sum.
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> sum([a, b], [])
[1, 2, 3, 4, 5, 6]
>>>
This works for any length and any element type of list:
>>> a = ['a', 'b', 'c', 'd']
>>> b = [1, 2, 3, 4]
>>> c = [1, 2]
>>> sum([a, b, c], [])
['a', 'b', 'c', 'd', 1, 2, 3, 4, 1, 2]
>>>
The reason I add [], is because the start argument is set to 0 by default, so it loops through the list and adds to start, but 0 + [1, 2, 3] would give an error, so if we set the start to []. It would add to [], and [] + [1, 2, 3] would work as expected.
I assume you want one of the two methods:
Keep duplicate elements
It is very easy. Just concatenate like a string:
def concat_list(l1,l2):
l3 = l1+l2
return l3
Next, if you want to eliminate duplicate elements
def concat_list(l1,l2):
l3 = []
for i in [l1,l2]:
for j in i:
if j not in l3:
# Check if element exists in final list, if no then add element to list
l3.append(j)
return l3
The solutions provided are for a single list. In case there are lists within a list and the merging of corresponding lists is required, the "+" operation through a for loop does the work.
a = [[1,2,3], [4,5,6]]
b = [[0,1,2], [7,8,9]]
for i in range(len(a)):
cc.append(a[i] + b[i])
Output: [[1, 2, 3, 0, 1, 2], [4, 5, 6, 7, 8, 9]]

Integrate elements in multiple lists into one list [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
How do I concatenate two lists in Python?
Example:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
Expected outcome:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
Use the + operator to combine the lists:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
joinedlist = listone + listtwo
Output:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
Python >= 3.5 alternative: [*l1, *l2]
Another alternative has been introduced via the acceptance of PEP 448 which deserves mentioning.
The PEP, titled Additional Unpacking Generalizations, generally reduced some syntactic restrictions when using the starred * expression in Python; with it, joining two lists (applies to any iterable) can now also be done with:
>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> joined_list = [*l1, *l2] # unpack both iterables in a list literal
>>> print(joined_list)
[1, 2, 3, 4, 5, 6]
This functionality was defined for Python 3.5, but it hasn't been backported to previous versions in the 3.x family. In unsupported versions a SyntaxError is going to be raised.
As with the other approaches, this too creates as shallow copy of the elements in the corresponding lists.
The upside to this approach is that you really don't need lists in order to perform it; anything that is iterable will do. As stated in the PEP:
This is also useful as a more readable way of summing iterables into a
list, such as my_list + list(my_tuple) + list(my_range) which is now
equivalent to just [*my_list, *my_tuple, *my_range].
So while addition with + would raise a TypeError due to type mismatch:
l = [1, 2, 3]
r = range(4, 7)
res = l + r
The following won't:
res = [*l, *r]
because it will first unpack the contents of the iterables and then simply create a list from the contents.
It's also possible to create a generator that simply iterates over the items in both lists using itertools.chain(). This allows you to chain lists (or any iterable) together for processing without copying the items to a new list:
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
You could also use the list.extend() method in order to add a list to the end of another one:
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
If you want to keep the original list intact, you can create a new list object, and extend both lists to it:
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
How do I concatenate two lists in Python?
As of 3.9, these are the most popular stdlib methods for concatenating two (or more) lists in Python.
Version Restrictions
In-Place?
Generalize to N lists?
a+b
-
No
sum([a, b, c], [])1
list(chain(a,b))2
>=2.3
No
list(chain(a, b, c))
[*a, *b]3
>=3.5
No
[*a, *b, *c]
a += b
-
Yes
No
a.extend(b)
-
Yes
No
Footnotes
This is a slick solution because of its succinctness. But sum performs concatenation in a pairwise fashion, which means this is a
quadratic operation as memory has to be allocated for each step. DO
NOT USE if your lists are large.
See chain
and
chain.from_iterable
from the docs. You will need to from itertools import chain first.
Concatenation is linear in memory, so this is the best in terms of
performance and version compatibility. chain.from_iterable was introduced in 2.6.
This method uses Additional Unpacking Generalizations (PEP 448), but cannot
generalize to N lists unless you manually unpack each one yourself.
a += b and a.extend(b) are more or less equivalent for all practical purposes. += when called on a list will internally call
list.__iadd__, which extends the first list by the second.
Performance
2-List Concatenation1
There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.
N-List Concatenation
Plots have been generated using the perfplot module. Code, for your reference.
1. The iadd (+=) and extend methods operate in-place, so a copy has to be generated each time before testing. To keep things fair, all methods have a pre-copy step for the left-hand list which can be ignored.
Comments on Other Solutions
DO NOT USE THE DUNDER METHOD list.__add__ directly in any way, shape or form. In fact, stay clear of dunder methods, and use the operators and operator functions like they were designed for. Python has careful semantics baked into these which are more complicated than just calling the dunder directly. Here is an example. So, to summarise, a.__add__(b) => BAD; a + b => GOOD.
Some answers here offer reduce(operator.add, [a, b]) for pairwise concatenation -- this is the same as sum([a, b], []) only more wordy.
Any method that uses set will drop duplicates and lose ordering. Use with caution.
for i in b: a.append(i) is more wordy, and slower than a.extend(b), which is single function call and more idiomatic. append is slower because of the semantics with which memory is allocated and grown for lists. See here for a similar discussion.
heapq.merge will work, but its use case is for merging sorted lists in linear time. Using it in any other situation is an anti-pattern.
yielding list elements from a function is an acceptable method, but chain does this faster and better (it has a code path in C, so it is fast).
operator.add(a, b) is an acceptable functional equivalent to a + b. It's use cases are mainly for dynamic method dispatch. Otherwise, prefer a + b which is shorter and more readable, in my opinion. YMMV.
You can use sets to obtain merged list of unique values
mergedlist = list(set(listone + listtwo))
This is quite simple, and I think it was even shown in the tutorial:
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
This question directly asks about joining two lists. However it's pretty high in search even when you are looking for a way of joining many lists (including the case when you joining zero lists).
I think the best option is to use list comprehensions:
>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> [x for xs in a for x in xs]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
You can create generators as well:
>>> map(str, (x for xs in a for x in xs))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
Old Answer
Consider this more generic approach:
a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])
Will output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Note, this also works correctly when a is [] or [[1,2,3]].
However, this can be done more efficiently with itertools:
a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))
If you don't need a list, but just an iterable, omit list().
Update
Alternative suggested by Patrick Collins in the comments could also work for you:
sum(a, [])
You could simply use the + or += operator as follows:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
Or:
c = []
a = [1, 2, 3]
b = [4, 5, 6]
c += (a + b)
Also, if you want the values in the merged list to be unique you can do:
c = list(set(a + b))
It's worth noting that the itertools.chain function accepts variable number of arguments:
>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']
If an iterable (tuple, list, generator, etc.) is the input, the from_iterable class method may be used:
>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']
For cases with a low number of lists you can simply add the lists together or use in-place unpacking (available in Python-3.5+):
In [1]: listone = [1, 2, 3]
...: listtwo = [4, 5, 6]
In [2]: listone + listtwo
Out[2]: [1, 2, 3, 4, 5, 6]
In [3]: [*listone, *listtwo]
Out[3]: [1, 2, 3, 4, 5, 6]
As a more general way for cases with more number of lists you can use chain.from_iterable()1 function from itertools module. Also, based on this answer this function is the best; or at least a very good way for flatting a nested list as well.
>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1. Note that `chain.from_iterable()` is available in Python 2.6 and later. In other versions, use `chain(*l)`.
With Python 3.3+ you can use yield from:
listone = [1,2,3]
listtwo = [4,5,6]
def merge(l1, l2):
yield from l1
yield from l2
>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]
Or, if you want to support an arbitrary number of iterators:
def merge(*iters):
for it in iters:
yield from it
>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]
If you want to merge the two lists in sorted form, you can use the merge function from the heapq library.
from heapq import merge
a = [1, 2, 4]
b = [2, 4, 6, 7]
print list(merge(a, b))
If you can't use the plus operator (+), you can use the operator import:
import operator
listone = [1,2,3]
listtwo = [4,5,6]
result = operator.add(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
Alternatively, you could also use the __add__ dunder function:
listone = [1,2,3]
listtwo = [4,5,6]
result = list.__add__(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
If you need to merge two ordered lists with complicated sorting rules, you might have to roll it yourself like in the following code (using a simple sorting rule for readability :-) ).
list1 = [1,2,5]
list2 = [2,3,4]
newlist = []
while list1 and list2:
if list1[0] == list2[0]:
newlist.append(list1.pop(0))
list2.pop(0)
elif list1[0] < list2[0]:
newlist.append(list1.pop(0))
else:
newlist.append(list2.pop(0))
if list1:
newlist.extend(list1)
if list2:
newlist.extend(list2)
assert(newlist == [1, 2, 3, 4, 5])
If you are using NumPy, you can concatenate two arrays of compatible dimensions with this command:
numpy.concatenate([a,b])
Use a simple list comprehension:
joined_list = [item for list_ in [list_one, list_two] for item in list_]
It has all the advantages of the newest approach of using Additional Unpacking Generalizations - i.e. you can concatenate an arbitrary number of different iterables (for example, lists, tuples, ranges, and generators) that way - and it's not limited to Python 3.5 or later.
Another way:
>>> listone = [1, 2, 3]
>>> listtwo = [4, 5, 6]
>>> joinedlist = [*listone, *listtwo]
>>> joinedlist
[1, 2, 3, 4, 5, 6]
>>>
list(set(listone) | set(listtwo))
The above code does not preserve order and removes duplicates from each list (but not from the concatenated list).
As already pointed out by many, itertools.chain() is the way to go if one needs to apply exactly the same treatment to both lists. In my case, I had a label and a flag which were different from one list to the other, so I needed something slightly more complex. As it turns out, behind the scenes itertools.chain() simply does the following:
for it in iterables:
for element in it:
yield element
(see https://docs.python.org/2/library/itertools.html), so I took inspiration from here and wrote something along these lines:
for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
print header + ':'
for path in iterable:
[...]
command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
print >> SCRIPT , command, flag, srcPath, mergedDirPath
[...]
The main points to understand here are that lists are just a special case of iterable, which are objects like any other; and that for ... in loops in python can work with tuple variables, so it is simple to loop on multiple variables at the same time.
You could use the append() method defined on list objects:
mergedlist =[]
for elem in listone:
mergedlist.append(elem)
for elem in listtwo:
mergedlist.append(elem)
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)
Output
>>> [1, 2, 3, 4, 5, 6]
In the above code, the "+" operator is used to concatenate the two lists into a single list.
Another solution
a = [1, 2, 3]
b = [4, 5, 6]
c = [] # Empty list in which we are going to append the values of list (a) and (b)
for i in a:
c.append(i)
for j in b:
c.append(j)
print(c)
Output
>>> [1, 2, 3, 4, 5, 6]
All the possible ways to join lists that I could find
import itertools
A = [1,3,5,7,9] + [2,4,6,8,10]
B = [1,3,5,7,9]
B.append([2,4,6,8,10])
C = [1,3,5,7,9]
C.extend([2,4,6,8,10])
D = list(zip([1,3,5,7,9],[2,4,6,8,10]))
E = [1,3,5,7,9]+[2,4,6,8,10]
F = list(set([1,3,5,7,9] + [2,4,6,8,10]))
G = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
G.append(a)
print("A: " + str(A))
print("B: " + str(B))
print("C: " + str(C))
print("D: " + str(D))
print("E: " + str(E))
print("F: " + str(F))
print("G: " + str(G))
Output
A: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
B: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
C: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
D: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
G: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
I recommend three methods to concatenate the list, but the first method is most recommended,
# Easiest and least complexity method <= recommended
listone = [1, 2, 3]
listtwo = [4, 5, 6]
newlist = listone + listtwo
print(newlist)
# Second-easiest method
newlist = listone.copy()
newlist.extend(listtwo)
print(newlist)
In the second method, I assign newlist to a copy of the listone, because I don't want to change listone.
# Third method
newlist = listone.copy()
for j in listtwo:
newlist.append(j)
print(newlist)
This is not a good way to concatenate lists because we are using a for loop to concatenate the lists. So time complexity is much higher than with the other two methods.
The most common method used to concatenate lists are the plus operator and the built-in method append, for example:
list = [1,2]
list = list + [3]
# list = [1,2,3]
list.append(3)
# list = [1,2,3]
list.append([3,4])
# list = [1,2,[3,4]]
For most of the cases, this will work, but the append function will not extend a list if one was added. Because that is not expected, you can use another method called extend. It should work with structures:
list = [1,2]
list.extend([3,4])
# list = [1,2,3,4]
A really concise way to combine a list of lists is
list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
reduce(list.__add__, list_of_lists)
which gives us
[1, 2, 3, 4, 5, 6, 7, 8, 9]
So there are two easy ways.
Using +: It creates a new list from provided lists
Example:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
Using extend: It appends new list to existing list. That means it does not create a separate list.
Example:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: %timeit a.extend(b)
10000000 loops, best of 3: 91.1 ns per loop
Thus we see that out of two of most popular methods, extend is efficient.
You could also just use sum.
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> sum([a, b], [])
[1, 2, 3, 4, 5, 6]
>>>
This works for any length and any element type of list:
>>> a = ['a', 'b', 'c', 'd']
>>> b = [1, 2, 3, 4]
>>> c = [1, 2]
>>> sum([a, b, c], [])
['a', 'b', 'c', 'd', 1, 2, 3, 4, 1, 2]
>>>
The reason I add [], is because the start argument is set to 0 by default, so it loops through the list and adds to start, but 0 + [1, 2, 3] would give an error, so if we set the start to []. It would add to [], and [] + [1, 2, 3] would work as expected.
I assume you want one of the two methods:
Keep duplicate elements
It is very easy. Just concatenate like a string:
def concat_list(l1,l2):
l3 = l1+l2
return l3
Next, if you want to eliminate duplicate elements
def concat_list(l1,l2):
l3 = []
for i in [l1,l2]:
for j in i:
if j not in l3:
# Check if element exists in final list, if no then add element to list
l3.append(j)
return l3
The solutions provided are for a single list. In case there are lists within a list and the merging of corresponding lists is required, the "+" operation through a for loop does the work.
a = [[1,2,3], [4,5,6]]
b = [[0,1,2], [7,8,9]]
for i in range(len(a)):
cc.append(a[i] + b[i])
Output: [[1, 2, 3, 0, 1, 2], [4, 5, 6, 7, 8, 9]]

Adding elements of lists in Python

How can I add up the elements of two lists in order to make a new list with the updated values. For example:
a = [1,2,3]
b = [3,4,5]
answer = [4,6,8]
I know this is a simple question, but I am new to this thing and cant find an answer anywhere else...
The zip() method would probably be the best way to add up columns, in that order.
a = [1, 3, 5] #your two starting lists
b = [2, 4, 6]
c = [] #the list you would print to
for x,y in zip(a, b): #zip takes 2 iterables; x and y are placeholders for them.
c.append(x + y) # adding on the the list
print c #final result
You may want to learn about list comprehensions, but for this task, it is not required.
>>> a = [1,2,3]
>>> b = [3,4,5]
>>> import operator
>>> map(operator.add, a, b)
[4, 6, 8]
For Python3, you need to use list with the result of map
>>> list(map(operator.add, a, b))
[4, 6, 8]
or just use the usual list comprehension
>>> [sum(x) for x in zip(a,b)]
[4, 6, 8]
>>> a = [1,2,3]
>>> b = [3,4,5]
>>> map(sum, zip(a, b))
[4, 6, 8]
You can use the itertools.izip_longest method to help with this:
def pairwise_sum(a, b):
for x, y in itertools.izip_longest(a, b, fillvalue=0):
yield x + y
You can then use it like this:
a = [1, 2, 3]
b = [3, 4, 5]
answer = list(pairwise_sum(a, b))

How to add two nested lists in parallel and append result to a new list in python

I'm trying to add all the elements of two unequal nested lists in parallel and append the result back to another new list, i've written a little hacky code that could add them but there's a lot of things wrong with the code, first i tried to make the pairs equal by appending 0's to the end of the list but the code still runs into the problems since the length of the first pair is 3 and the length of the second pair is 4, i also tried using map but i couldn't add an integer and a NoneType,
import pdb
import itertools
x = [[2,3,3], [5,0,3]]
y = [[0,3], [2,3,3,3]]
for idx, (a, b) in enumerate(itertools.zip_longest(x, y)):
while len(a) < len(b):
x[idx].append(0)
while len(b) < len(a):
y[idx].append(0)
print(x, y)
new_list = list()
for i in zip(x, y):
for idx, j in enumerate(i):
for ind, a in enumerate(j):
val = x[idx][ind] + y[idx][ind]
new_list.append(val)
print(new_list)
the final result should be like this
[2, 6, 3, 7, 3, 6, 3]
You can simply use itertools.zip_longest and fill-in with 0, like this
>>> from itertools import zip_longest as zip
>>> x = [[2, 3, 3], [5, 0, 3]]
>>> y = [[0, 3], [2, 3, 3, 3]]
>>> [k + l for i, j in zip(x, y, fillvalue=[0]) for k, l in zip(i, j, fillvalue=0)]
[2, 6, 3, 7, 3, 6, 3]
This would would work even if x and y have unequal number of elements,
>>> from itertools import zip_longest as zip
>>> x = [[2, 3, 3], [5, 0, 3], [1]]
>>> y = [[0, 3], [2, 3, 3, 3]]
>>> [k + l for i, j in zip(x, y, fillvalue=[0]) for k, l in zip(i, j, fillvalue=0)]
[2, 6, 3, 7, 3, 6, 3, 1]
Note that, when we zip x and y, we use [0] as fillvalue. And when we zip i and j we use 0 as the fillvalue.
So, if the number of lists in x and y are not equal, then [0] will be used fill-in and when the number of elements in i and j are not equal, 0 will be used as the fill-in.
You can use fillvalue=0 in izip_longest to get ride of checking for validations then use map function for sum the zipped items:
from itertools import chain,zip_longest
list(chain.from_iterable(map(sum,zip_longest(i,j,fillvalue=0)) for i,j in zip_longest(x, y)))
[2, 6, 3, 7, 3, 6, 3]
Note that if you want to iterate over the result you don't have to use list (its just for demonstrating the result).
zip_longest is very helpful here:
x = [[2,3,3], [5,0,3]]
y = [[0,3], [2,3,3,3]]
from itertools import zip_longest
res = []
for list1, list2 in zip_longest(x, y, fillvalue=[0]):
for value1, value2 in zip_longest(list1, list2, fillvalue=0):
res.append(value1 + value2)
The fill value pads the list or sublist with the given value. In our case a new list with [0] for the outer loop and 0 for the inner loop.
Writing this a nested list comprehension does the same but may take more time to read and understand the code. Using more lines can make reading and understanding faster. Of course, this depends very much on the person reading the code.
from itertools import zip_longest
new_list = [a + b
for listpair in zip(x, y)
for a, b in zip_longest(*listpair, fillvalue=0)]

Categories

Resources