So I have an array of about 40 items and need to find n permutations of the list. I know I can use itertools.permutations but that would give me all 40! different orderings which would take longer.
Is there a way I can create exactly n permutations of the list?
itertools.permutations gives you an iterator over the permutations of your list. You can pull out values one by one, the function does not precompute anything.
If you just want the first n permutations that are produced without any further constraints, islice the result of permutations.
>>> from itertools import permutations, islice
>>> perms = islice(permutations(yourlist), n)
Computing of permutations will only start once you iterate over perms - either directly with a for loop or by making a container (list, tuple, set, ...) out of it.
Related
I have a list, l1, which I have generated all combinations of length 2 using itertools.combinations. I intend to loop through these combinations, and perform an operation on them. For simplicity, this code simply prints combination a.
import itertools
l1 = [1,2,3,4,5]
for a in itertools.combinations(l1,2):
print(a)
Is there any way to randomise the order that the combinations are looped through? random.shuffle does not appear to work, as itertools.combinations has no length.
Why not save the combinations as a variable and then shuffle?:
import itertools
import random
l1 = [1,2,3,4,5]
combs = list(itertools.combinations(l1,2))
random.shuffle(combs)
for a in combs:
print(a)
I would like to have all possible combinations of lists of a given size.
Lets say for example, I have a given list K, such as K = [3, 5, 2]. With the following code I get what I desire. But how do I generalize this for any list of a given size, without just adding for loops?
assignment= []
for l in range(K[0]):
for m in range(K[1]):
for n in range(K[2]):
a = [l,m,n]
assignment.append(a)
The itertools library can often help with things like this. itertools.product() in particular, using * to pass it a list or iterator of ranges:
list(itertools.product(*(range(n) for n in K))
or
list(itertools.product(*map(range, K)))
I need to do this: I have list of integers, i make all possible combinations containing 3 of these numbers, and output is list containing sums of these combinations. (not sum of all combinations together, but for each combination one sum)
My algorithm do it in this way: make list of all possible combinations, then count sum of each combination and save it into list, what is too uneffective if number of integers is large. Here is little sample in python:
import itertools
array=[1,2,3,4]
combs=[]
els = [list(x) for x in itertools.combinations(array, 3)]
combs.extend(els)
result=list(map(sum, combs))
Could you please come up with some more effective solution? Maybe if there is some way of making it a loop where there isn't made a list of combinations at first and counted sum of each combination at second but rather it straight counts sum of just created combination, saves it into list and then continues to another one until all combinations and sums are done.
sum() works with any iterable, not just lists. You could make the code more efficient by applying it directly to the combinations' tuples:
result = [sum(c) for c in itertools.combinations(array, 3)]
If you want to process the result lazily, you can use a generator expression as well:
result = (sum(c) for c in itertools.combinations(array, 3))
I have used the following script to generate all combinations:
import itertools
x = 7
my_list = range(1, 11)
for k in [x]:
for sublist in itertools.combinations(my_list, k):
print sublist
For the second part I will take 6 random elements from range(1, 11). Let's call them my_second_list.
I need to generate the minimum number of combinations of my_list in order to obtain at least one combination to include let's say 5 elements from my_second_list.
Any ideas on how to do that?
import itertools
x = 7
my_list = range(1,11)
for k in [x]: # isn't this just 7?
your_output = (combination for combination in itertools.combinations(my_list,k) if all(element in combination for element in [1,2,3,4,5]))
It's ugly as heck, but that's how I'd do it (if I'm understanding your question correctly. You're trying to get only those combinations that contain a certain subset of items, right? If you want all combinations BEFORE and INCLUDING that first combination that contains the subset of items, I'd do:
accumulator = list()
subset = [1,2,3,4,5] # or whatever
for k in [x]:
for combination in itertools.combinations(my_list,k):
accumulator.append(combination)
if all(el in combination for el in subset):
break
Depending on your exact use case you may want to consider defining subset as a set (e.g. {1,2,3,4,5}) and do subset.issubset(set(combination)) but it's hard to tell if that's better or not without doing some profiling.
I know you can take the pairwise cross product of lists in the ways posted here: Pairwise crossproduct in Python
but I want to take a list L and a positive integer n and return the cross-product of L with itself n times. Is there a built in way to do this or will I just have to iterate the pairwise cross-product?
(edit: "cartesian product")
You are looking for itertools.product:
Cartesian product of input iterables.
Equivalent to nested for-loops in a generator expression. For example,
product(A, B) returns the same as ((x,y) for x in A for y in B).
The nested loops cycle like an odometer with the rightmost element
advancing on every iteration. This pattern creates a lexicographic
ordering so that if the input’s iterables are sorted, the product
tuples are emitted in sorted order.
To compute the product of an iterable with itself, specify the number
of repetitions with the optional repeat keyword argument. For example,
product(A, repeat=4) means the same as product(A, A, A, A).
So you just need to do
itertools.product(L, repeat=n)