This question already has answers here:
How to get the cartesian product of multiple lists
(17 answers)
Closed 10 months ago.
I have the following list of lists:
data = [[1,2,3],[4,5,6]]
and I want to generate something like the following:
[1,4]
[1,5]
[1,6]
[2,4]
[2,5]
[2,6]
[3,4]
[3,5]
[3,6]
What can produce the expected result? To clarify, I'm looking for all unique pairs of 1 item from each of the two sublists.
import itertools
data = [[1,2,3],[4,5,6]]
print(list(itertools.product(*data)))
Output:
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
You can use itertools.product() with list unpacking to generate tuples containing one element from each sublist. You can then use map() to transform each of those tuples to lists.
from itertools import product
list(map(list, product(*data)))
This outputs:
[[1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6]]
result = []
for x in data[0]:
for y in data[1]:
result.append([x, y])
or one line:
[(x,y) for x in data[0] for y in data[1]]
that will give you a list of tuples
list of lists:
list(map(list, [(x,y) for x in data[0] for y in data[1]]))
Related
This question already has answers here:
How to merge lists into a list of tuples?
(10 answers)
Closed 1 year ago.
What I have
l1 = [1,2,3,4,5]
l2 = [6,7,8,9,10]
What i want:
l3 = [ [1,6], [2,7], [3,8], [4,9], [5,10] ]
Assuming both lists have the same length:
l1 = [1,2,3,4,5]
l2 = [6,7,8,9,10]
output = [[l1[i], l2[i]] for i in range(0, len(l1))]
print(output) # [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
Use zip:
zipped = zip(l1, l2)
result = [ x for x in zipped ]
# Result:
# [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
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)]
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]]
This question already has answers here:
Transpose list of lists
(14 answers)
Closed 8 years ago.
Let's say I have a SINGLE list [[1,2,3],[4,5,6]]
How do I transpose them so they will be: [[1, 4], [2, 5], [3, 6]]?
Do I have to use the zip function? Is the zip function the easiest way?
def m_transpose(m):
trans = zip(m)
return trans
Using zip and *splat is the easiest way in pure Python.
>>> list_ = [[1,2,3],[4,5,6]]
>>> zip(*list_)
[(1, 4), (2, 5), (3, 6)]
Note that you get tuples inside instead of lists. If you need the lists, use map(list, zip(*l)).
If you're open to using numpy instead of a list of lists, then using the .T attribute is even easier:
>>> import numpy as np
>>> a = np.array([[1,2,3],[4,5,6]])
>>> print(*a)
[1 2 3] [4 5 6]
>>> print(*a.T)
[1 4] [2 5] [3 6]
The exact way of use zip() and get what you want is:
>>> l = [[1,2,3],[4,5,6]]
>>> [list(x) for x in zip(*l)]
>>> [[1, 4], [2, 5], [3, 6]]
This code use list keyword for casting the tuples returned by zip into lists.
You can use map with None as the first parameter:
>>> li=[[1,2,3],[4,5,6]]
>>> map(None, *li)
[(1, 4), (2, 5), (3, 6)]
Unlike zip it works on uneven lists:
>>> li=[[1,2,3],[4,5,6,7]]
>>> map(None, *li)
[(1, 4), (2, 5), (3, 6), (None, 7)]
>>> zip(*li)
[(1, 4), (2, 5), (3, 6)]
# ^^ 7 missing...
Then call map again with list as the first parameter if you want the sub elements to be lists instead of tuples:
>>> map(list, map(None, *li))
[[1, 4], [2, 5], [3, 6]]
(Note: the use of map with None to transpose a matrix is not supported in Python 3.x. Use zip_longest from itertools to get the same functionality...)
zip() doesn't seem to do what you wanted, using zip() you get a list of tuples. This should work though:
>>> new_list = []
>>> old_list = [[1,2,3],[4,5,6]]
>>> for index in range(len(old_list[0])):
... new_list.append([old_list[0][index], old_list[1][index]])
...
>>> new_list
[[1, 4], [2, 5], [3, 6]]
So I'm trying to get rid of some nested loops through map() and have trouble with a specific case.
I have two lists:
List1 = [1, 2, 3, 4, 5]
List2 = [[1, 2, 3], [5], [1, 6], [1, 0, 9, 10], [1, 5, 2]]
So basically list1 and list 2 are the same lengths, but list 2 is a list of lists of variable lengths.
I want to call some function on the equivalent of;
(1,1), (1,2), (1,3), (2,5), (3,1), (3,6), (4,1), (4,0), (4,9) (4,10), (5,1), (5,5), (5,2)
using map. The first parameter of the tuple is from List1 and the second one is from the i'th equivalent of list1 on list2, with the sublist expanded.
so right now I have:
map(function, zip(list1, list2))
but I cannot see how I could expand list2 to get what I just described. I think it might involve list comprehensions, but I'm having a little trouble and trial and error didn't get me very far.
Another question is, if the inner function in this nested loop is susceptible to get called millions of times, will map() be significantly faster than just a for loop?
Its simple with list comprehension, like this
list1 = [1, 2, 3, 4, 5]
list2 = [[1, 2, 3], [5], [1, 6], [1, 0, 9, 10], [1, 5, 2]]
print [(item1, s) for item1, item2 in zip(list1, list2) for s in item2]
Output
[(1, 1), (1, 2), (1, 3), (2, 5), (3, 1), (3, 6), (4, 1), (4, 0), (4, 9), (4, 10), (5, 1), (5, 5), (5, 2)]
This oneliner is just a short version of
result = []
for item1, item2 in zip(list1, list2):
for s in item2:
result.append((item1, s))
List comprehensions or lambda functions can help, but the solution will be too lengthy and unreadable. Probably a naive loop is better?
def join(list1, list2):
for head, tail in zip(list1, list2):
for thing in tail:
yield (head, thing)
This is a generator. You can use it the following way:
pairs = join(list1, list2)
for pair in pairs:
# do anything with pair
Or you want to store this right in memory instead of this incremental generator?
A solution using itertools (no temporary list in memory):
from itertools import *
a = chain.from_iterable( product([i], j) for i, j in izip( List1, List2 ) )
You can transform this in a list using :
list(a)
Or just walk elements using a loop.