Related
I'd like to make nested list
given_list = [[0, 1, 2], [0, 1, 2], [0, 1, 2]] # each element : range(0, n), num of element : m
new_list = [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], ..., [2, 2, 2]] # total num : n^m
How do I make it?
I tried to overlap the for statement m times, but I don't think it's pythonic.
Looks like you are trying to compute the product of the lists in given_list:
> from itertools import product
> list(product(*given_list))
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (0, 2, 1), (0, 2, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0), (2, 2, 1), (2, 2, 2)]
If you really need a list of lists, rather than a list of tuples, you'll have to call list on each element.
[list(t) for t in product(*given_list)]
I am trying to create a list of tuples that consists of all the variations of a set of numbers. However I want to remove any variants from the list that are the same sequence but offset by a position or two. For example:
(-1,1,2), (1,2,-1) & (2,-1,1) I would only want the first one.
Here's where I'm up to:
import itertools as it
list = [-1, 0, 1, 2]
cycles = []
list_cycle_3 = it.permutations(cycles, 3)
list_cycle_4 = it.permutations(cycles, 4)
for item in list_cycle_3:
cycles.append(item)
for item in list_cycle_4:
cycles.append(item)
print(cycles)
This results in:
[(-1, 0, 1), (-1, 0, 2), (-1, 1, 0), (-1, 1, 2), (-1, 2, 0), (-1, 2, 1),
(0, -1, 1), (0, -1, 2), (0, 1, -1), (0, 1, 2), (0, 2, -1), (0, 2, 1),
(1, -1, 0), (1, -1, 2), (1, 0, -1), (1, 0, 2), (1, 2, -1), (1, 2, 0),
(2, -1, 0), (2, -1, 1), (2, 0, -1), (2, 0, 1), (2, 1, -1), (2, 1, 0),
(-1, 0, 1, 2), (-1, 0, 2, 1), (-1, 1, 0, 2), (-1, 1, 2, 0), (-1, 2, 0, 1), (-1, 2, 1, 0), (0, -1, 1, 2), (0, -1, 2, 1), (0, 1, -1, 2), (0, 1, 2, -1),
(0, 2, -1, 1), (0, 2, 1, -1), (1, -1, 0, 2), (1, -1, 2, 0), (1, 0, -1, 2),
(1, 0, 2, -1), (1, 2, -1, 0), (1, 2, 0, -1), (2, -1, 0, 1), (2, -1, 1, 0),
(2, 0, -1, 1), (2, 0, 1, -1), (2, 1, -1, 0), (2, 1, 0, -1)]
So what do I do next to filter the results so I only have the results I want, which are:
[(-1, 0, 1), (-1, 0, 2), (-1, 1, 0), (-1, 1, 2), (-1, 2, 0), (-1, 2, 1),
(0, 1, 2), (0, 2, 1), (-1, 0, 1, 2), (-1, 0, 2, 1), (-1, 1, 0, 2),
(-1, 1, 2, 0), (-1, 2, 0, 1), (-1, 2, 1, 0)]
If it helps a simple difference between the lists are that the list I want is all the tuples starting with -1, and the tuples where there is no -1 starting with 0
Start with a list that does not contain the number that you want to filter against:
For example, you'll only need the ones that starts with 0. Then your list is
l = [-1, 1, 2]
Find all the two element permutatations and filter them as you like.
Ant then add 0 as the first element by mapping your result set.
Example:
In [2]: from itertools import permutations
In [3]: l = [-1, 1, 2]
In [4]: p = permutations(l, 2)
In [5]: [(0, *t) for t in p]
Out[5]: [(0, -1, 1), (0, -1, 2), (0, 1, -1), (0, 1, 2), (0, 2, -1), (0, 2, 1)]
You could do a similar trick for, say, the ones that does not have -1 in them and start with 0 which is omit -1 and 0 from your list and then add 0 as the first element into your result sets items.
And do not override reserved keywords in your code:
list = [...] # do not do that
l=[(-1, 0, 1), (-1, 0, 2), (-1, 1, 0), (-1, 1, 2), (-1, 2, 0), (-1, 2, 1),
(0, -1, 1), (0, -1, 2), (0, 1, -1), (0, 1, 2), (0, 2, -1), (0, 2, 1),
(1, -1, 0), (1, -1, 2), (1, 0, -1), (1, 0, 2), (1, 2, -1), (1, 2, 0),
(2, -1, 0), (2, -1, 1), (2, 0, -1), (2, 0, 1), (2, 1, -1), (2, 1, 0),
(-1, 0, 1, 2), (-1, 0, 2, 1), (-1, 1, 0, 2), (-1, 1, 2, 0), (-1, 2, 0, 1), (-1, 2, 1, 0), (0, -1, 1, 2), (0, -1, 2, 1), (0, 1, -1, 2), (0, 1, 2, -1),
(0, 2, -1, 1), (0, 2, 1, -1), (1, -1, 0, 2), (1, -1, 2, 0), (1, 0, -1, 2),
(1, 0, 2, -1), (1, 2, -1, 0), (1, 2, 0, -1), (2, -1, 0, 1), (2, -1, 1, 0),
(2, 0, -1, 1), (2, 0, 1, -1), (2, 1, -1, 0), (2, 1, 0, -1)]
l2=[]
for i in l:
if i[0] == -1 :
l2.append(i)
print(l2)
this code works
output
[(-1, 0, 1), (-1, 0, 2), (-1, 1, 0), (-1, 1, 2), (-1, 2, 0), (-1, 2, 1), (-1, 0, 1, 2), (-1, 0, 2, 1), (-1, 1, 0, 2), (-1, 1, 2, 0), (-1, 2, 0, 1), (-1, 2, 1, 0)]
I have a set of numbers [1, 2, 4, 1]. Now, I want to generate all possible combinations from this set of size k (example k = 3). All the generated output sets must not be duplicate
Example : [1, 2, 1] and [2, 1, 1] are the same sets but they should not be selected. Only one of them should appear. Is it possible using combinations from itertools in Python?
import itertools
x = [1, 2, 1]
print([p for p in itertools.product(x, repeat=3)])
I have tried using itertools.product but it doesnt work and
using combinations from itertools is getting duplicates
I have tried using itertools.combinations
print([p for p in set(itertools.combinations(x, r=3))])
If I give the following input
x = [-1, 0, 1, 2, -1, -4]
The ouput generated for r = 3 is
[(0, -1, -4), (-1, -1, -4), (-1, 1, -4), (0, 2, -1), (-1, 0, 2), (-1, 2, -4), (0, 1, 2), (2, -1, -4), (-1, 0, -1), (0, 1, -4), (1, 2, -4), (-1, 0, 1), (-1, 1, 2), (0, 2, -4), (-1, 1, -1), (-1, 2, -1), (1, 2, -1), (0, 1, -1), (-1, 0, -4), (1, -1, -4)]
(-1, 0, 1) and (0, 1, -1) are duplicate sets with same combinations. I am not sure how to overcome this.
These are called multisets, and we can easily obtain the combinations of these with the sympy module.
from sympy.utilities.iterables import multiset_combinations
list(multiset_combinations([1, 2, 4, 1], 3))
[[1, 1, 2], [1, 1, 4], [1, 2, 4]]
And here is the example by #EdedkiOkoh:
x = [-1, 0, 1, 2, -1, -4]
list(multiset_combinations(x, 3))
[[-4, -1, -1],
[-4, -1, 0],
[-4, -1, 1],
[-4, -1, 2],
[-4, 0, 1],
[-4, 0, 2],
[-4, 1, 2],
[-1, -1, 0],
[-1, -1, 1],
[-1, -1, 2],
[-1, 0, 1],
[-1, 0, 2],
[-1, 1, 2],
[0, 1, 2]]
You can use python's set datatype to remove those duplicates since sets will only contain the unique combinations:
import itertools as it
x = [-1, 0, 1, 2, -1, -4]
permutations = [p for p in set(it.combinations(x, r=3))]
print(permutations)
Output:
[(0, 1, 2),
(-1, 1, -1),
(-1, 2, -1),
(0, -1, -4),
(-1, -1, -4),
(-1, 1, -4),
(-1, 2, -4),
(2, -1, -4),
(1, 2, -4),
(-1, 0, 1),
(1, 2, -1),
(-1, 0, -4),
(-1, 0, 2),
(-1, 0, -1),
(-1, 1, 2),
(0, 2, -4),
(0, 2, -1),
(0, 1, -4),
(1, -1, -4),
(0, 1, -1)]
Then use can use the following line:
unique_permutations = set(tuple(sorted(t)) for t in permutations)
Output:
{(-4, -1, -1),
(-4, -1, 0),
(-4, -1, 1),
(-4, -1, 2),
(-4, 0, 1),
(-4, 0, 2),
(-4, 1, 2),
(-1, -1, 0),
(-1, -1, 1),
(-1, -1, 2),
(-1, 0, 1),
(-1, 0, 2),
(-1, 1, 2),
(0, 1, 2)}
What about getting the combinations and then taking only the unique ones by keying a dictionary with the frozenset result of the combinations. This will only use generators until creating the dictionary.
combs1, combs2 = itertools.tee(itertools.combinations(x, r=3))
res = list(dict(zip(map(frozenset, combs1), combs2)).values())
This question already has answers here:
How to use list comprehension with .extend list method? [duplicate]
(2 answers)
How can I use a list comprehension to extend a list in python? [duplicate]
(6 answers)
Python: How to extend or append multiple elements in list comprehension format?
(2 answers)
Closed 4 years ago.
Is there a 1-liner equivalent (using list comprehension) for the following:
a = []
for i in range(6):
a.extend(((-i,i,0,2),(-i-1,i,0,6)))
a = tuple(a)
I was thinking something like
tuple(((-i,i,0,2),(-i-1,i,0,6)) for i in range(6))
but this gives:
(((0, 0, 0, 2), (-1, 0, 0, 6)),
((-1, 1, 0, 2), (-2, 1, 0, 6)),
((-2, 2, 0, 2), (-3, 2, 0, 6)),
((-3, 3, 0, 2), (-4, 3, 0, 6)),
((-4, 4, 0, 2), (-5, 4, 0, 6)),
((-5, 5, 0, 2), (-6, 5, 0, 6)))
which is not what I want.
Desired output
((0, 0, 0, 2),
(-1, 0, 0, 6),
(-1, 1, 0, 2),
(-2, 1, 0, 6),
(-2, 2, 0, 2),
(-3, 2, 0, 6),
(-3, 3, 0, 2),
(-4, 3, 0, 6),
(-4, 4, 0, 2),
(-5, 4, 0, 6),
(-5, 5, 0, 2),
(-6, 5, 0, 6))
You can use a nested list comprehension.
>>> [t for i in range(6) for t in ((-i,i,0,2), (-i-1,i,0,6))]
>>>
[(0, 0, 0, 2),
(-1, 0, 0, 6),
(-1, 1, 0, 2),
(-2, 1, 0, 6),
(-2, 2, 0, 2),
(-3, 2, 0, 6),
(-3, 3, 0, 2),
(-4, 3, 0, 6),
(-4, 4, 0, 2),
(-5, 4, 0, 6),
(-5, 5, 0, 2),
(-6, 5, 0, 6)]
It reads like this
[what I want (t) | for loops as if writing non-listcomp code]
and is thus equivalent to
result = []
for i in range(6):
for t in ((-i,i,0,2), (-i-1,i,0,6)):
result.append(t)
This question already has answers here:
Python itertools permutations how to include repeating characters [duplicate]
(2 answers)
How to get the cartesian product of multiple lists
(17 answers)
Closed 5 years ago.
from itertools import permutations
l = [0, 1, 2, 3, 4]
x = permutations (l, 3)
I get the following :
(0, 1, 2) , (0, 1, 3), ...., (0, 2, 1), (0, 2, 3), (0,2,4),...., (4, 3, 0), (4, 3, 1),
(4, 3, 2)
Which is what was expected.
But what i need is :
(0, 0, 0), (0, 0, 1), ...., (0, 0, 4), (0, 1, 0), (0, 1, 1)........
How to achieve this ?
What you need is a permutation with replacement, or a product, but itertool's permutations produces permutations without replacement. You can calculate the product yourself:
[(x,y,z) for x in l for y in l for z in l]
#[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 0), ...
Or use the namesake function from itertools:
list(itertools.product(l,repeat=3))
# [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 0),...
The latter approach is more efficient.
You need to use product , not using permutations, from itertools module like this example:
from itertools import product
l = [0, 1, 2, 3, 4]
# Or:
# b = list(product(l, repeat=3))
b = list(product(l,l,l))
print(b)
Output:
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), ..., (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 4, 4)]
You need product and not permutation
from itertools import product
l = [0, 1, 2, 3, 4]
b = list(product(l, repeat=3))