itertools: Cartesian product of permutations [duplicate] - python

This question already has answers here:
Expanding tuples into arguments
(5 answers)
Closed 8 months ago.
Using pythons itertools, I'd like to create an iterator over the outer product of all permutations of a bunch of lists. An explicit example:
import itertools
A = [1,2,3]
B = [4,5]
C = [6,7]
for x in itertools.product(itertools.permutations(A),itertools.permutations(B),itertools.permutations(C)):
print x
While this works, I'd like to generalize it to an arbitrary list of lists. I tried:
for x in itertools.product(map(itertools.permutations,[A,B,C])):
print x
but it did not do what I intended. The expected output is:
((1, 2, 3), (4, 5), (6, 7))
((1, 2, 3), (4, 5), (7, 6))
((1, 2, 3), (5, 4), (6, 7))
((1, 2, 3), (5, 4), (7, 6))
((1, 3, 2), (4, 5), (6, 7))
((1, 3, 2), (4, 5), (7, 6))
((1, 3, 2), (5, 4), (6, 7))
((1, 3, 2), (5, 4), (7, 6))
((2, 1, 3), (4, 5), (6, 7))
((2, 1, 3), (4, 5), (7, 6))
((2, 1, 3), (5, 4), (6, 7))
((2, 1, 3), (5, 4), (7, 6))
((2, 3, 1), (4, 5), (6, 7))
((2, 3, 1), (4, 5), (7, 6))
((2, 3, 1), (5, 4), (6, 7))
((2, 3, 1), (5, 4), (7, 6))
((3, 1, 2), (4, 5), (6, 7))
((3, 1, 2), (4, 5), (7, 6))
((3, 1, 2), (5, 4), (6, 7))
((3, 1, 2), (5, 4), (7, 6))
((3, 2, 1), (4, 5), (6, 7))
((3, 2, 1), (4, 5), (7, 6))
((3, 2, 1), (5, 4), (6, 7))
((3, 2, 1), (5, 4), (7, 6))

You missed the * to unpack the list into 3 arguments
itertools.product(*map(itertools.permutations,[A,B,C]))

Related

Find all combinations of tuples inside of a list

I am trying to find all permutations of the items inside of the tuples while in the list of length 2. The order of the tuples in relation to each other does not matter.
perm = [(3, 6), (6, 8), (4, 1), (7, 4), (5, 3),
(1, 9), (2, 5), (4, 8), (5, 1), (3, 7),
(6, 9), (10, 2), (7, 10), (8, 2), (9, 10)]
An example of one permutation of the above list would be:
perm = [(6, 3), (6, 8), (4, 1), (7, 4), (5, 3),
(1, 9), (2, 5), (4, 8), (5, 1), (3, 7),
(6, 9), (10, 2), (7, 10), (8, 2), (9, 10)]
Another example permutation would be:
perm = [(6, 3), (8, 6), (1, 4), (4, 7), (3, 5),
(9, 1), (5, 2), (8, 4), (1, 5), (7, 3),
(9, 6), (2, 10), (10, 7), (2, 8), (10, 9)]
In the end, the length of the list of permutations should be 32768, because each tuple is either swapped or not swapped, and 2^15 = 32768. I do not care about the order of the tuples in relation to each other, only the permutations of the items inside of the tuples.
I have tried to use itertools permute, combinations, and product, but I haven't been able to get the desired result.
You can use product:
from itertools import product
lst = [(3, 6), (6, 8), (4, 1), (7, 4), (5, 3),
(1, 9), (2, 5), (4, 8), (5, 1), (3, 7),
(6, 9), (10, 2), (7, 10), (8, 2), (9, 10)]
output = product(*([(x, y), (y, x)] for x, y in lst))
output = list(output) # if you want a list, rather than a generator
print(len(output))
# 32768
print(output[0])
# ((3, 6), (6, 8), (4, 1), (7, 4), (5, 3), (1, 9), (2, 5), (4, 8), (5, 1), (3, 7), (6, 9), (10, 2), (7, 10), (8, 2), (9, 10))
print(output[-1])
# ((6, 3), (8, 6), (1, 4), (4, 7), (3, 5), (9, 1), (5, 2), (8, 4), (1, 5), (7, 3), (9, 6), (2, 10), (10, 7), (2, 8), (10, 9))
The key is to write something like
output = product([(3,6), (6,3)], [(6,8), (8,6)], ..., [(9,10), (10,9)])
in a generic way so that any input list would work, which is done by the generator expression and unpacking (*).

How to create set from list of tuples

I want to work out all the permutations of three dice rolls where sum is over 7.
This is still a work in progress but efforts to calculate sets don't work.
import pandas as pd
import random
count = 0
digits = [roll for roll in range(1,7)]
digits
digits_all = [random.sample(digits, 2) for d in digits]
def dice_role(r = digits_all):
count =0
digits_all_roll_1 = r
digits_all_roll_2 = r
digits_all_roll_3 = r
#return digits_all_roll_1, digits_all_roll_2, digits_all_roll_3
data = []
for d in digits_all_roll_1:
data.append(tuple(d))
for e in digits_all_roll_2:
data.append(tuple(e))
for f in digits_all_roll_3:
data.append(tuple(f))
return data
results = dice_role()
Results
[(3, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 2),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(2, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(3, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 2),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(2, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(3, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 2),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(2, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(3, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 2),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(2, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(3, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 2),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(2, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(3, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 2),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(5, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(6, 5),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1),
(2, 1),
(3, 1),
(6, 5),
(5, 2),
(5, 1),
(6, 5),
(2, 1)]
)
1
What can I try next?
If I understand the problem correctly, you could do it like this:
from itertools import combinations_with_replacement as CWR
result = {t for t in CWR(range(1, 7), 3) if sum(t) > 7}
print(result)
Output:
{(3, 5, 6), (1, 6, 6), (2, 2, 5), (4, 4, 4), (1, 2, 5), (4, 5, 6), (3, 3, 5), (1, 3, 6), (3, 4, 4), (1, 4, 5), (5, 5, 6), (2, 4, 5), (2, 3, 3), (2, 3, 6), (1, 1, 6), (1, 5, 6), (2, 2, 4), (3, 5, 5), (4, 4, 6), (4, 5, 5), (2, 5, 6), (4, 6, 6), (6, 6, 6), (1, 4, 4), (5, 5, 5), (3, 4, 6), (3, 3, 4), (1, 3, 5), (3, 6, 6), (2, 3, 5), (2, 4, 4), (1, 5, 5), (5, 6, 6), (2, 2, 6), (2, 5, 5), (1, 2, 6), (2, 6, 6), (4, 4, 5), (1, 4, 6), (1, 3, 4), (3, 3, 3), (3, 3, 6), (3, 4, 5), (2, 3, 4), (2, 4, 6)}

Sort a list of tuples by the first element of the tuple without removing duplicates [duplicate]

I have a list of tuples:
self.gridKeys = self.gridMap.keys() # The keys of the instance of the GridMap (It returns the product of every possible combination of positions in the specified grid, in tuples.)
print self.gridKeys
self.gridKeys:
[(7, 3), (6, 9), (0, 7), (1, 6), (3, 7), (2, 5), (8, 5), (5, 8), (4, 0), (9, 0), (6, 7), (5, 5), (7, 6), (0, 4), (1, 1), (3, 2), (2, 6), (8, 2), (4, 5), (9, 3), (6, 0), (7, 5), (0, 1), (3, 1), (9, 9), (7, 8), (2, 1), (8, 9), (9, 4), (5, 1), (7, 2), (1, 5), (3, 6), (2, 2), (8, 6), (4, 1), (9, 7), (6, 4), (5, 4), (7, 1), (0, 5), (1, 0), (0, 8), (3, 5), (2, 7), (8, 3), (4, 6), (9, 2), (6, 1), (5, 7), (7, 4), (0, 2), (1, 3), (4, 8), (3, 0), (2, 8), (9, 8), (8, 0), (6, 2), (5, 0), (1, 4), (3, 9), (2, 3), (1, 9), (8, 7), (4, 2), (9, 6), (6, 5), (5, 3), (7, 0), (6, 8), (0, 6), (1, 7), (0, 9), (3, 4), (2, 4), (8, 4), (5, 9), (4, 7), (9, 1), (6, 6), (5, 6), (7, 7), (0, 3), (1, 2), (4, 9), (3, 3), (2, 9), (8, 1), (4, 4), (6, 3), (0, 0), (7, 9), (3, 8), (2, 0), (1, 8), (8, 8), (4, 3), (9, 5), (5, 2)]
After sorting:
self.gridKeys = self.gridMap.keys() # The keys of the instance of the GridMap (It returns the product of every possible combination of positions in the specified grid, in tuples.)
self.gridKeys.sort() # They're dicts, so they need to be properly ordered for further XML-analysis.
print self.gridKeys
self.gridKeys:
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]
The first element of each tuple is the "x", and the second the "y". I'm moving objects in a list through iteration and using these keys (So, if I want to move something in the x axis, I have to go through all the column, and that might be causing a horrid problem that I'm not being able to solve).
How can I sort the tuples in this way?:
[(1, 0), (2, 0), (3, 0), (4, 0), (5, 0), ...]
You can use the key parameter of the sort function, to sort the tuples. The function of key parameter, is to come up with a value which has to be used to compare two objects. So, in your case, if you want the sort to use only the first element in the tuple, you can do something like this
self.gridKeys.sort(key=lambda x: x[0])
If you want to use only the second element in the tuple, then
self.gridKeys.sort(key=lambda x: x[1])
sort function will pass each and every element in the list to the lambda function you pass as parameter to key and it will use the value it returns, to compare two objects in the list. So, in your case, lets say you have two items in the list like this
data = [(1, 3), (1, 2)]
and if you want to sort by the second element, then you would do
data.sort(key=lambda x: x[1])
First it passes (1, 3) to the lambda function which returns the element at index 1, which is 3 and that will represent this tuple during the comparison. The same way, 2 will be used for the second tuple.
This should do the trick
import operator
self.gridKeys.sort(key=operator.itemgetter(1))
While thefourtheye's solution is correct in the strict sense that it is exactly what you asked for in the title. It may not be actually what you want. It may be better to take it a bit farther via sorting by the reverse of the tuple instead.
self.gridKeys.sort(key=lambda x:tuple(reversed(x)))
This forces you to have an ordering like:
[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), ...]
Rather than having the first element be unordered like:
[(4, 0), (9, 0), (6, 0), (1, 0), (3, 0), ...]
Which is what I get when using:
self.gridKeys.sort(key=lambda x: x[1])
By default Python does a lexicographical sort from left to right. Reversing the tuple effectively makes Python do the lexicographical sort from right to left.

Iterate list of numbers

I have a list of 13 numbers, each of them can be equal any number from 1 to 9.
I need to look over all possible variants of these numbers in the list: when number1=1 and number2=1/2/3/4/5/6/7/8/9 (exclusive 0), and so on. Then I need to do the same for number1=2 and so on.
I can't quite comprehend how to do it - apparently through 'for' cycle?
for x in range(1,10):
A=[x for i in range(13)]
for i in range(len(A)):
for t in range(1,10):
A[i]=t
print A
This doesn't work out.
I would recommend using itertools.product.
>>> from itertools import product
>>> list(product(range(1, 10), repeat=2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]
However, I wouldn't recommend doing it for 13 numbers. Why? Take a look:
>>> len(list(product(range(1, 10), repeat=2)))
81
9^2 = 81. So to compute it for 13, you would need to compute 9^13 tuples with length 13. That will take quite a while.
Luckily itertools.product returns a generator object, so you can iterate through the values one by one if you wish. Just don't try to turn it into a list.

Use Python to create 2D coordinate

I am truly a novice in Python. Now, I am doing a project which involves creating a list of 2D coordinates. The coordinates should be uniformly placed, using a square grid (10*10), like(0,0)(0,1)(0,2)(0,3)...(0,10)(1,0)(1,2)(1,3)...(2,0)(2,1)(2,2)...(10,10).
Here is my code:
coordinate = []
x = 0
y = 0
while y < 10:
while x < 10:
coordinate.append((x,y))
x += 1
coordinate.append((x,y))
y += 1
print(coordinate)
But I can only get: [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9)]
How can I rewrite my code to get all the points?
It's common to use a couple of for-loops to achieve this:
coordinates = []
for x in range(11):
for y in range(11):
coordinates.append((x, y))
It's also common to simplify this by flattening it into a list comprehension:
coordinates = [(x,y) for x in range(11) for y in range(11)]
from itertools import product
x = (0, 1, 2)
test = product(x, x)
Result:
>>> for ele in test:
... print ele
...
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
Note that test is a generator, so you probably would want to use list(test).
To actually answer your question, you forgot to reset x back to zero after the first run through x=0..9:
coordinate = []
y = 0
while y < 10:
x = 0
while x < 10:
coordinate.append((x,y))
x += 1
coordinate.append((x,y))
y += 1
print(coordinate)
Feel free to use all other variants, of course.
Use itertools.product:
>>> from itertools import product
>>> list(product(range(11), repeat=2))
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)]
The above code is equivalent to this nested list comprehension:
>>> [(x, y) for x in range(11) for y in range(11)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)]
Use a for loop. It lets you iterate over things called "iterators". range is a built-in function which returns an iterator from its starting argument (first argument) inclusive. up to its ending argument (second argument) non-inclusive. Thus range(0,11) will return 0,1,2,...,10.
coordinate = []
for y in range(0, 11):
for x in range(0, 11):
coordinate.append((x,y))
print(coordinate)
For more information on for loops in Python, check out the official wiki page.

Categories

Resources