Generate all combinations of positive and negative
Question:
I have this list of tuples
a = [(1, 2), (2, 1)]
And need all of the possible combinations of negative and positive:
b = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
I’ve tried using itertools.product()
:
xs = list(product(*([[i, -j] for (i, j) in b])))
ys = list(product(*([[-i, j] for (i, j) in b])))
xs + ys
But it does not generate the correct numbers:
>>>xs + ys
[(1, 2), (1, -1), (-2, 2), (-2, -1), (-1, -2), (-1, 1), (2, -2), (2, 1)]
Answers:
Code:
a = [(1, 2), (2, 1)]
res1=[]
for x in a:
for i in [x[0], -x[0]]:
for j in [x[1], -x[1]]:
res1.append((i,j))
#Through list comprehension
res2=[(i,j) for x in a for i in [x[0],-x[0]] for j in [x[1],-x[1]]]
#Output
print(res1)
print(res2)
Output:
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
Using itertools
Code:
import itertools
a=[(1, 2), (2, 1)]
xs=list(itertools.product(*map(lambda x: (x, -x), a[0])))
ys=list(itertools.product(*map(lambda x: (x, -x), a[1])))
print(xs+ys) #Same output as above
a = [(1, 2), (2, 1)]
b = []
for x, y in a:
for i in [-1, 1]:
for j in [-1, 1]:
b.append((x*i, y*j))
print(b)
You should perform product
on the signs instead:
[(sx * x, sy * y) for x, y in a for sx, sy in product((1, -1), repeat=2)]
You can also include a
in a nested product
:
[(sx * x, sy * y) for (x, y), (sx, sy) in product(a, product((1, -1), repeat=2))]
or map the sequences of numbers and signs to the multiplication operator:
from operator import mul
[tuple(map(mul, *t)) for t in product(a, product((1, -1), repeat=2))]
All three expressions would return:
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
(Note: currently the question is ambiguous. Once they clarify, I might have to update these.)
For tuples of any length:
[p for t in a for p in product(*((x, -x) for x in t))]
Or with operator.neg
:
[p for t in a for p in product(*zip(t, map(neg, t)))]
Or without any Python looping, using chain
/repeat
/starmap
from itertools
(this is a direct conversion from the above solution):
[*chain(*starmap(product, map(zip, a, map(map, repeat(neg), a))))]
For tuples of length 2:
[(X, Y) for x, y in a for X in (x, -x) for Y in (y, -y)]
Here is the solution along the lines you are trying to solve…
xs = list(itertools.product(*([[(i),(-i)] for (i,j) in var_b])))
ys = list(itertools.product(*([[(j),(-j)] for (i,j) in var_b])))
print (xs + ys)
Output
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
I have this list of tuples
a = [(1, 2), (2, 1)]
And need all of the possible combinations of negative and positive:
b = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
I’ve tried using itertools.product()
:
xs = list(product(*([[i, -j] for (i, j) in b])))
ys = list(product(*([[-i, j] for (i, j) in b])))
xs + ys
But it does not generate the correct numbers:
>>>xs + ys
[(1, 2), (1, -1), (-2, 2), (-2, -1), (-1, -2), (-1, 1), (2, -2), (2, 1)]
Code:
a = [(1, 2), (2, 1)]
res1=[]
for x in a:
for i in [x[0], -x[0]]:
for j in [x[1], -x[1]]:
res1.append((i,j))
#Through list comprehension
res2=[(i,j) for x in a for i in [x[0],-x[0]] for j in [x[1],-x[1]]]
#Output
print(res1)
print(res2)
Output:
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
Using itertools
Code:
import itertools
a=[(1, 2), (2, 1)]
xs=list(itertools.product(*map(lambda x: (x, -x), a[0])))
ys=list(itertools.product(*map(lambda x: (x, -x), a[1])))
print(xs+ys) #Same output as above
a = [(1, 2), (2, 1)]
b = []
for x, y in a:
for i in [-1, 1]:
for j in [-1, 1]:
b.append((x*i, y*j))
print(b)
You should perform product
on the signs instead:
[(sx * x, sy * y) for x, y in a for sx, sy in product((1, -1), repeat=2)]
You can also include a
in a nested product
:
[(sx * x, sy * y) for (x, y), (sx, sy) in product(a, product((1, -1), repeat=2))]
or map the sequences of numbers and signs to the multiplication operator:
from operator import mul
[tuple(map(mul, *t)) for t in product(a, product((1, -1), repeat=2))]
All three expressions would return:
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
(Note: currently the question is ambiguous. Once they clarify, I might have to update these.)
For tuples of any length:
[p for t in a for p in product(*((x, -x) for x in t))]
Or with operator.neg
:
[p for t in a for p in product(*zip(t, map(neg, t)))]
Or without any Python looping, using chain
/repeat
/starmap
from itertools
(this is a direct conversion from the above solution):
[*chain(*starmap(product, map(zip, a, map(map, repeat(neg), a))))]
For tuples of length 2:
[(X, Y) for x, y in a for X in (x, -x) for Y in (y, -y)]
Here is the solution along the lines you are trying to solve…
xs = list(itertools.product(*([[(i),(-i)] for (i,j) in var_b])))
ys = list(itertools.product(*([[(j),(-j)] for (i,j) in var_b])))
print (xs + ys)
Output
[(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]