python itertools product with steps - python

Currently, I have a NumPy array:
a = np.array([[1,2],[3,4],[5,6]])
And I am doing the product operation in itertools, but I want to add a step function.
For example:
[ x for x in itertools.product(*a) ]
Result in:
[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]
For the target output with step (1,1,2):
[(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)]
I can't figure it out, here is the problem.

Just use a list slice:
In [578]: import itertools
In [579]: a=[[1,2],[3,4],[5,6]]
In [580]: list(itertools.product(*a))[::2]
Out[580]: [(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)]
There may be a itertools tools to do this as well.
In [586]: list(itertools.islice(itertools.product(*a), None, None,2))
Out[586]: [(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)]

This should do:
step = (1,1,2)
[ x for x in itertools.product(*[a[i,::s] for i,s in enumerate(step)])]

You can use this code. I think your problem is solve.
import itertools
print(list(itertools.product(*[[1,2],[3,4],[5,6]]))[::2])

Related

Merge list of list with duplicates

Input list
[(1, 0, 3), '21:40:44', (1, 3, 9), (1, 4, 6), '.273']
[(1, 0, 3), '21:43:37', (1, 3, 9), (1, 4, 6), '.060']
[(1, 0, 3), '21:45:27', (1, 3, 9), (1, 4, 6), '.410']
And the result should be like:
[(1, 0, 3), ['21:40:44', '21:43:37', '21:45:27'], (1, 3, 9), (1, 4, 6), ['.273', '.060', '.410']
The goal is to reduce the duplicates, the unique elements in a column should be stored in a list.
How about using zip. It will merge the 3 list and give you output with duplicates. later use set to remove duplicates. and since you don not want list of tuple for single element only, use list(set(x))[0] if len(set(x))==1 else list(set(x))
a=[(1, 0, 3), '21:40:44', (1, 3, 9), (1, 4, 6), '.273']
b=[(1, 0, 3), '21:43:37', (1, 3, 9), (1, 4, 6), '.060']
c=[(1, 0, 3), '21:45:27', (1, 3, 9), (1, 4, 6), '.410']
l=[list(set(x))[0] if len(set(x))==1 else list(set(x)) for x in list(zip(a,b,c))]
print(l)
>>>[(1, 0, 3), ['21:45:27', '21:40:44', '21:43:37'], (1, 3, 9), (1, 4, 6), ['.060', '.273', '.410']]
the simplest way is this:
in_data = [
[(1, 0, 3), '21:40:44', (1, 3, 9), (1, 4, 6), '.273'],
[(1, 0, 3), '21:43:37', (1, 3, 9), (1, 4, 6), '.060'],
[(1, 0, 3), '21:45:27', (1, 3, 9), (1, 4, 6), '.410']
]
res = []
for i in range(len(in_data[0])):
data = list(set([x[i] for x in in_data ]))
data = data[0] if len(data) == 1 else data
res.append(data)
print(res)
>>> [(1, 0, 3), ['21:43:37', '21:40:44', '21:45:27'], (1, 3, 9), (1, 4, 6), ['.273', '.060', '.410']]

How to generate dynamically combinations of list in python

I want to generate combination dynamically in python, I have a var sessionperweeks (between 2 and 6)
if sessionperweeks==2
for i in range(0,7):
for j in range(i+1,7):
combins.append([i,j])
if sessionperweeks==3
for i in range(0,7):
for j in range(i+1,7):
for k in range(j+1,7):
combins.append([i,j,k])
and so on
Here you go, using combinations from itertools to pick sessions per week from 0-6:
from itertools import combinations
sessionsperweek = int(input("Enter sessions per week:"))
combins = list(combinations(range(7), sessionsperweek))
print("Your possible combinations are:")
print(combins)
Example run with 2 (since OP updated):
Enter sessions per week:2
Your possible combinations are:
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
Example run:
Enter sessions per week:6
Your possible combinations are:
[(0, 1, 2, 3, 4, 5), (0, 1, 2, 3, 4, 6), (0, 1, 2, 3, 5, 6), (0, 1, 2, 4, 5, 6), (0, 1, 3, 4, 5, 6), (0, 2, 3, 4, 5, 6), (1, 2, 3, 4, 5, 6)]

Getting all the combinations of a Numpy Array

If I have a Numpy array like X=np.array([1,2,3,4,5])
I want to put all of the combinations of these numbers into an array.
How would I go about getting an array with each row being a combination of X and the length is how ever many combinations there are?
Assuming from your question you are actually looking for permutations:
from itertools import permutations
import numpy as np
x = np.array([1, 2, 3, 4, 5])
perm_array = np.asarray([p for p in permutations(x)])
print(perm_array.shape)
# prints(120, 5)
Each row of perm_array will contain a permutation of your input.
Watch out that the number of permutations grows extremely quickly!
Available in itertools:
from itertools import combinations
X=np.array([1,2,3,4,5])
X_combinations = {} # dictionary key r: combinations of rank r.
for r in range(len(X) + 1):
X_combinations[r] = list(combinations(X, r))
from pprint import pprint
pprint(X_combinations)
output:
{0: [()],
1: [(1,), (2,), (3,), (4,), (5,)],
2: [(1, 2),
(1, 3),
(1, 4),
(1, 5),
(2, 3),
(2, 4),
(2, 5),
(3, 4),
(3, 5),
(4, 5)],
3: [(1, 2, 3),
(1, 2, 4),
(1, 2, 5),
(1, 3, 4),
(1, 3, 5),
(1, 4, 5),
(2, 3, 4),
(2, 3, 5),
(2, 4, 5),
(3, 4, 5)],
4: [(1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 4, 5), (1, 3, 4, 5), (2, 3, 4, 5)],
5: [(1, 2, 3, 4, 5)]}

Best way to go from tuple pairs of numbers to one tuple of all the individual numbers

How can i get this
nums = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
to this? The second item of each tuple is the first item of the next tuple.
[0, 1, 2, 3, 4, 5, 6, 7, 8]
I did:
>>> zip(*nums)[0]
(0, 1, 2, 3, 4, 5, 6, 7)
But it gives me everything except the last element and then i had to use some bad code to get it to the correct result so i was looking for an elegant solution.
Not sure what your general case is, but
[nums[0][0]] + [x[1] for x in nums]
For your example
range(nums[-1][-1] + 1)
also works, can you describe what you are trying to do rather than just giving one simple case?
>>> nums = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
>>> i = iter(nums)
>>> next(i) + tuple(y for x,y in i)
(0, 1, 2, 3, 4, 5, 6, 7, 8)
More efficient version using itertools
>>> from itertools import chain
>>> nums = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
>>> i = iter(nums)
>>> list(chain(next(i),(y for x,y in i)))
[0, 1, 2, 3, 4, 5, 6, 7, 8]
def flatten(E):
if E in [[], ()]:
return []
elif type(E) not in [list, tuple]:
return [E]
else:
return flatten(E[0]) + flatten(E[1:])
def declutter(L):
s = set()
answer = []
for i in L:
if i not in s:
s.add(i)
answer.append(i)
return answer
>>> nums = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
>>> declutter(flatten(nums))
[0, 1, 2, 3, 4, 5, 6, 7, 8]
Hope this helps

What's the standard way of doing this sort in Python?

Imagine I have a list of tuples in this format:
(1, 2, 3)
(1, 0, 2)
(3, 9 , 11)
(0, 2, 8)
(2, 3, 4)
(2, 4, 5)
(2, 7, 8)
....
How could I sort the list by the first element of the tuples, and then by the second? I'd like to get to this list:
(0, 2, 8)
(1, 0, 2)
(1, 2, 3)
(2, 3, 4)
(2, 4, 5)
(2, 7, 8)
(3, 9 , 11)
I was thinking to do a sort for the first element, and then go through the list, and build a hash with subarrays. I will probably overcomplicate things :), and this is why I asked for other ways of doing this sort.
Why not simply let python sort the list for you ?
my_list = [
(1, 2, 3),
(1, 0, 2),
(3, 9 , 11),
(0, 2, 8),
(2, 3, 4),
(2, 4, 5),
(2, 7, 8),
]
print sorted(my_list)
>>>[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]
Python automagically does the right thing:
>>> a = [(1, 2, 3), (1, 0, 2), (3, 9, 11), (0, 2, 8), (2, 3, 4), (2, 4, 5), (2, 7, 8)]
>>> a.sort()
>>> a
[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]
Tuples are already sorted that way.
Try this:
#!/usr/bin/python2
l = [
(1, 2, 3),
(1, 0, 2),
(3, 9 , 11),
(0, 2, 8),
(2, 3, 4),
(2, 4, 5),
(2, 7, 8),
]
l.sort()
print l
If you don't mind sorting by all three elements, this is really trivial:
>>> l = [(1, 2, 3), (1, 0, 2), (3, 9, 11), (0, 2, 8), (2, 3, 4), (2, 4, 5), (2, 7, 8)]
>>> l.sort()
>>> l
[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]
>>> x = [
... (1, 2, 3),
... (1, 0, 2),
... (3, 9 , 11),
... (0, 2, 8),
... (2, 3, 4),
... (2, 4, 5),
... (2, 7, 8),
... ]
>>> x.sort()
>>> x
[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]

Categories