Related
This question already has answers here:
How to merge lists into a list of tuples?
(10 answers)
Closed 2 years ago.
For example, if I have:
A = [1, 2, 3]` & `B = [4, 5, 6]
and I would like to have:
C = [[1, 4], [2, 5], [3, 6]]
You can use tuple and zip to meet this requirement.
Sample code -
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = tuple(zip(a,b))
>>> print(c)
((1, 4), (2, 5), (3, 6))
There is a builtin function called zip for this:
[list(ab) for ab in zip(a,b)]
Or using map and zip:
list(map(list, zip(a,b)))
Both return:
[[1, 4], [2, 5], [3, 6]]
You can do this:
a = [1,2,3]
b = [4,5,6]
c = [list(x) for x in zip(a, b)]
In [110]: A = [1,2,3]
In [111]: B = [4,5,6]
In [112]: list(zip(A,B))
Out[112]: [(1, 4), (2, 5), (3, 6)]
For example, if these are my two lists:
a=[1,2,3,4,5]
b=[6,7,8,9,10]
Then what I'm trying to do is to figure out a way to get:
c=[[1,6],[2,7],[3,8],[4,9],[5,10]]
Sorry for the probably basic question. These are numpy arrays if that makes a difference.
If you want a numpy array as a result, you can build it using array.T:
In [15]: a=np.array([1,2,3,4,5])
In [16]: b=np.array([6,7,8,9,10])
In [17]: np.array([a,b]).T
Out[17]:
array([[ 1, 6],
[ 2, 7],
[ 3, 8],
[ 4, 9],
[ 5, 10]])
Reference: What is the equivalent of "zip()" in Python's numpy?
One approach is using list comprehension and zip:
>>> [[i, j] for i, j in zip(a,b)]
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
I don't use numpy, but maybe by using zip:
>>> a=[1,2,3,4,5]
>>> b=[6,7,8,9,10]
>>> list(zip(a,b))
[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
It returns a list of tuples though.
Just use np.transpose:
>>> np.transpose([a, b])
array([[ 1, 6],
[ 2, 7],
[ 3, 8],
[ 4, 9],
[ 5, 10]])
If you want the result as list just call tolist() afterwards:
>>> np.transpose([a, b]).tolist()
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
d = []
for i in range(0, 5):
d.append([a[i], b[i])
Is a simple way to create a new 2D list with element pairs. Using the zip() function as others have pointed out is also viable.
I'm pretty sure there is an easier or more pythonic way than this.
c = [list(x) for x in zip(a,b)]
This outputs a list of lists, instead of just doing list(zip(a,b) that outputs a list of tuples. This combines list comprehension and zip
Also avoids the tuple unpacking of [[i,j] for i,j in zip(a,b)]
not sure whats more efficient though
zip(*iterables) Make an iterator that aggregates elements from each of the iterables.
https://docs.python.org/3/library/functions.html#zip
There are multiple ways to do this.
a = [1, 2, 3, 4, 5]
b = [6, 7, 8, 9, 10]
If you just need to access the elements and not modify them, you can use the zip function:
zip(a, b)
>[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
If you actually need a list of lists, then you can use a list comprehension:
[[a[i], b[i]] for i in range(len(a))]
>[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
And finally, if you need a numpy array as a result, use the Transpose function:
import numpy as np
np.concatenate([[a], [b]]).T
>array([[1, 6],
[2, 7],
[3, 8],
[4, 9],
[5, 10]])
This will give you what you want.
a = [1,2,3,4,5]
b = [6,7,8,9,10]
c = [list(x) for x in zip(a, b)]
with no libraries, you could use:
a = [1,2,3,4,5]
b = [6,7,8,9,10]
c = [[a[i],b[i]] for i in range(len(a))]
How 'pythonic-ly', do I turn this:
[[x1,y1], [x2,y2]]
Into:
[(x1,x2),(y1,y2)]
Use a zip and unpacking operator.
>>> l = [['x1','y1'], ['x2','y2']]
>>> zip(*l)
[('x1', 'x2'), ('y1', 'y2')]
Handled more case in give test case.
If there are items in list which have different length.
In [19]: a
Out[19]: [[1, 2], [3, 4], [5, 6], [7, 8, 9]]
In [20]: import itertools
In [21]: b = itertools.izip_longest(*a)
In [22]: list(b)
Out[22]: [(1, 3, 5, 7), (2, 4, 6, 8), (None, None, None, 9)]
This question already has answers here:
How to merge lists into a list of tuples?
(10 answers)
Closed 7 years ago.
I am currently learning list comprehension in Python. How would I do the following:
l1 = [2,4,6,8]
l2 = [2,3,4,5]
l = [*some list comprehension*]
so that
l = [[2,2],[4,3],[6,4],[8,5]]
EDIT: Can I do this without zip?
You want the zip function.
Example -
>>> l1 = [2,4,6,8]
>>> l2 = [2,3,4,5]
>>>
>>> l = list(zip(l1,l2))
>>> l
[(2, 2), (4, 3), (6, 4), (8, 5)]
If you want the inner lists to be of type list instead of tuple -
>>> l = [list(x) for x in zip(l1,l2)]
>>> l
[[2, 2], [4, 3], [6, 4], [8, 5]]
In python 3.x, zip returns an iterator, so if you do not want a list, but just want to iterate over each combined (zipped) element, you can just directly use - zip(l1,l2) .
As it is asked in the question, to do it without zip function, you can use enumerate function to get the index as well as the element from one list and then use the index to get the element from second list.
>>> l = [[x,l2[i]] for i,x in enumerate(l1)]
>>> l
[[2, 2], [4, 3], [6, 4], [8, 5]]
But this would not work unless both lists have same size.Also not sure why you would want to do it without zip .
Using list comprehension and zip:
>>> l1 = [2, 4, 6, 8]
>>> l2 = [2, 3, 4, 5]
>>> [[x, y] for x, y in zip(l1, l2)]
[[2, 2], [4, 3], [6, 4], [8, 5]]
You can use zip as
>>> l1 = [2,4,6,8]
>>> l2 = [2,3,4,5]
>>> zip(l1,l2)
[(2, 2), (4, 3), (6, 4), (8, 5)]
>>> [ list(x) for x in zip(l1,l2) ]
[[2, 2], [4, 3], [6, 4], [8, 5]]
I have a list whose nested list's size may vary with the multiple of 2. Currently, in this example, the nested list's length is 4.
a_list = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
According to length, I am trying to break the list to get the following result in the best possible pythonic way:
a = [[1,2], [5,6], [9,10]]
b = [[3,4], [7,8], [11,12]]
and if nested list's length is 6, then
c = [[..], [..], [..]]
Its kind of a transpose of a nested list but with sets of 2 values in a single row not to be transposed.
Using list comprehension:
>>> a_list = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> a = [x[:2] for x in a_list]
>>> b = [x[2:] for x in a_list]
>>> a
[[1, 2], [5, 6], [9, 10]]
>>> b
[[3, 4], [7, 8], [11, 12]]
More general solution:
>>> [[x[i:i+2] for x in a_list] for i in range(0, len(a_list[0]), 2)]
[[[1, 2], [5, 6], [9, 10]],
[[3, 4], [7, 8], [11, 12]]]
I'd hesitate to call this "pythonic", since it's pretty much illegible, but:
>>> a, b = zip(*(zip(*[iter(s)]*2) for s in a_list))
>>> a
((1, 2), (5, 6), (9, 10))
>>> b
((3, 4), (7, 8), (11, 12))
Also works for 6-item lists:
>>> a_list = [[1,2,3,4,100,102],[5,6,7,8,103,104],[9,10,11,12,105,106]]
>>> a, b, c = zip(*(zip(*[iter(s)]*2) for s in a_list))
>>> a
((1, 2), (5, 6), (9, 10))
>>> b
((3, 4), (7, 8), (11, 12))
>>> c
((100, 102), (103, 104), (105, 106))
Almost the same as falsetru's answer, but first the nested lists are split into chunks of size 2 and then all of them are zipped together.
>>> a_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> zip(*([j[i*2: i*2 + 2] for i in range(len(j) / 2)] for j in a_list))
[([1, 2], [5, 6], [9, 10]), ([3, 4], [7, 8], [11, 12])]
>>> a_list = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
>>> zip(*([j[i*2: i*2 + 2] for i in range(len(j) / 2)] for j in a_list))
[([1, 2], [7, 8]), ([3, 4], [9, 10]), ([5, 6], [11, 12])]
>>> a_list = [[1,2,3,4,100,102],[5,6,7,8,103,104],[9,10,11,12,105,106]]
>>> zip(*([j[i*2: i*2 + 2] for i in range(len(j) / 2)] for j in a_list))
[([1, 2], [5, 6], [9, 10]), ([3, 4], [7, 8], [11, 12]), ([100, 102], [103, 104], [105, 106])]
A Fast way is using numpy.hsplit :
>>> import numpy
>>> numpy.hsplit(numpy.array(a_list),2)
[array([[ 1, 2],[ 5, 6],[ 9, 10]]),array([[ 3, 4],[ 7, 8],[11, 12]])]
Since readability is pythonic, here's a simpler iterator-based solution (without the neat tricks that #Zero used to turn it into a one-liner):
First, an iterator that turns a list [1,2,3,4,5,6] into [(1, 2), (3, 4), (5, 6)].
def pairs(lst):
it=iter(lst)
return list(zip(it, it)) # Return a list of pairs drawn from the same iterator
The list a_list can be transformed into a list of such pair lists as follows:
a_list = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
pair_list = [ pairs(row) for row in a_list ]
Finally, we need to effectively transpose this list, making a list of the first pair/element from each sublist, another list of the second one, etc. A nice idiom for transposing a list is zip(*some_list). Let's use it to make the transformation requested by the OP:
a, b = zip(*pair_list)
or to collect any number of generated lists in one list:
results = list( zip(*pair_list) )
Feel free to pack these into a one-liner (though I wouldn't):
results = list(zip( *(pairs(row) for row in a_list) ))