Related
I would like to find all combinations of my list of numbers without the pair being the same. The code I've written below gives me all combinations. So, I also get [1, 1], [2, 2] and [3, 3], which I'd like to remove.
nr_list = [1, 2, 3]
combinations = []
for a in nr_list:
for b in nr_list:
pair = [a, b]
combinations.append(pair)
print(combinations)
from itertools import permutations
nr_list = [1, 2, 3]
print(list(permutations(nr_list, 2)))
# [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
Similar question: link
Just don't append the pair to the combinations if the items in pair are equal ie if pair[0] != pair[1]:
Try this code
nr_list = [1, 2, 3]
combinations = []
for a in nr_list:
for b in nr_list:
if(a!=b):
pair = [a, b]
combinations.append(pair)
print(combinations)
I have a list of, say, 3 players:
[1, 2, 3]
How can I generate, in python, a list of lists, of the form:
[[1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]
representing all teams that can be formed with the above players?
You could use itertools.combinations() where we can set r parameter to all lengths from 1 to length of our list (x), to get all possible combinations that are going to be flattened in list comprehension.
from itertools import combinations
x = [1, 2, 3]
result = [c for i in range(1, len(x)+1) for c in combinations(x, i)]
print(result) # -> [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
Use https://docs.python.org/3/library/itertools.html#itertools.combinations
It does exactly what you want.
import itertools
players = [1, 2, 3]
print(list(itertools.chain.from_iterable(itertools.combinations(players, r) for r in range(1, len(players) + 1))))
Output:
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
This is probably the most efficient answer due to the use of itertools.chain
You can use itertools.combinations with a given size to generate fixed size combinations. In order to generalize, you can just use a for loop over all the sizes. The code would look like this:
import itertools
my_list = [1, 2, 3]
for L in range(0, len(my_list)+1):
for subset in itertools.combinations(my_list, L):
print(subset)
Itertools is you friend for these kind of operations:
import itertools
l = [1, 2, 3]
l = [list(x) for y in range(1,len(l)+1) for x in itertools.combinations(l,y) ]
print(l)
Gives:
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
You can use itertools. What you want to do is generate powerset of the given list.
>>> import itertools
>>> a=[1,2,3]
>>> out=[]
>>> for i in range(len(a)+1):
out+=list(itertools.combinations(a,i))
>>> out
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
>>>
You can write recursive function to generate powerset as follows:
>>> def powerset(s,idx,curr,out):
if idx==len(s):
out.append(curr)
return
(powerset(s,idx+1,curr+[s[idx]],out))
(powerset(s,idx+1,curr,out))
return sorted(out,key=lambda x:len(x))
>>> z=powerset(a,0,[],[])
>>> z
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
I used this way to make all combinations:
import itertools
lst = [[1, 2, 3], [1,2,2,4]]
combs = []
for i in xrange(1, len(lst)+1):
combs.append(i)
els = [list(x) for x in itertools.combinations(lst, i)]
combs.append(els)
But what I want is that each list includes every possible combinations of elements inside. With the solution above, each element pairs are scattered. How can I solve it?
Are you looking for something like this?
import itertools
lst = [1, 2, 3], [1, 2, 2, 4]
combs = []
for i in range(len(lst)):
els = [list(x) for x in itertools.combinations(lst[i], 2)]
combs.append(els)
print(combs)
Output
[[[1, 2], [1, 3], [2, 3]], [[1, 2], [1, 2], [1, 4], [2, 2], [2, 4], [2, 4]]]
Since you said, you want - each element in its own list make pairs and put back in that list, so i am assuming that [1, 2, 3] should be converted to [[1, 2], [1, 3], [2, 3]]. The above example does the same thing!
Update
If you want to generate all possible combinations (of length greater than 1) from those lists, then you can do something like this.
import itertools
lst = [1, 2, 3], [1, 2, 2, 4]
combs = []
for i in range(len(lst)):
temp_list = []
for j in range(len(lst[i])+1):
if j < 2: # skipping zero and one length combinations
continue
els = [x for x in itertools.combinations(lst[i], j)]
temp_list.extend(els)
# remove duplicate combinations
new_list = []
[new_list.append(i) for i in temp_list if not new_list.count(i)]
combs.append(new_list)
print(combs)
Output
[[(1, 2), (1, 3), (2, 3), (1, 2, 3)], [(1, 2), (1, 4), (2, 2), (2, 4),
(1, 2, 2), (1, 2, 4), (2, 2, 4), (1, 2, 2, 4)]]
I'm facing a problem involving lists. I have a nested
list like:
A = [ [0,2,3,4], [0,1,1,2] ]
where the first list holds the the y and the second list holds the x coordinate for four different points. I'd like to obtain a list:
B = [[0,0], [1,2], [1,3], [2,4]]
where each list represents a point. Is there a simple pythonic way to do that or must I deal with for loops? Thank you in advance and sorry if a similar question has been already posted.
That's what the zip function is for.
>>> A = [ [0,2,3,4], [0,1,1,2] ]
>>> B = [list(x) for x in zip(*A[::-1])]
>>> B
[[0, 0], [1, 2], [1, 3], [2, 4]]
if you don't need your elements to be lists (i.e. tuples are fine, too), this shortens to
>>> zip(*A[::-1])
[(0, 0), (1, 2), (1, 3), (2, 4)]
in Python 2 and
>>> list(zip(*A[::-1]))
[(0, 0), (1, 2), (1, 3), (2, 4)]
in Python 3.
Explanation of the syntax:
A[::-1] is reversing A:
>>> A[::-1]
[[0, 1, 1, 2], [0, 2, 3, 4]]
The reversed list is then passed in an unpacked form (notice the *) to the zip function, which is equivalent to
>>> zip([0, 1, 1, 2], [0, 2, 3, 4])
[(0, 0), (1, 2), (1, 3), (2, 4)]
and zip will build tuples from the first, second, ..., n'th elements from each iterable.
edit:
Minor improvement:
>>> zip(*reversed(A))
[(0, 0), (1, 2), (1, 3), (2, 4)]
should be more memory efficient because reversed gives you an iterator, A[::-1] gives you a complete list, which we don't really need.
A couple things. First, those are Python lists which roughly correspond to ArrayLists in other programming languages. Second you asked for tuple elements in the result, but the code you posted has elements of type list.
Use the zip builtin function.
B = list(zip(*A[::-1]))
print(B)
yields
[(0, 0), (2, 1), (3, 1), (4, 2)]
If you want elements of type list, you can do the following.
B = list(map(list, zip(*A[::-1])))
print(B)
yields
[[0, 0], [2, 1], [3, 1], [4, 2]]
numpy can do it also, in a perhaps more readable way:
In [88]: y,x=A;numpy.transpose([x,y]).tolist()
Out[88]: [[0, 0], [1, 2], [1, 3], [2, 4]]
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]]