Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get Cartesian products of some subsets of my lists, as well as the product of the entire list of lists?

It's probably on Google, but I'm having a hard time putting into words what I'm trying to do. itertools.product is close, but I also want it to give me smaller combinations whereas itertools only gives combinations across all lists. It would probably be easier to explain in an example:

Example of lists I want to combine: [[a,b,c],[d,e,f],[g,h,i]]

Itertools gives back: [a,d,g],[a,d,h]....[c,f,h],[c,f,i] (27 results)

Output I am looking for: The above, plus:

[a,d],[a,e],[a,f],[b,d],[b,e],[b,f],[c,d],[c,e],[c,f],[d,g],[d,h],[d,i],[e,g],[e,h],[e,i],[f,g],[f,h],[f,i]

There would be a total of 45 results. Note that I'm only looking for combinations between the lists that are next to each other (don't want [a,g] returned). The lists will not be this simple either, there will be a set of 10 lists with 3-4 characters each.

The only line of code I have for this is: list(itertools.product(*thelist))]. I just don't know where to go next on what I'm trying to do here. I have a feeling there's some way to do this with itertools, I just can't figure it out.

like image 713
SCAND1UM Avatar asked Sep 03 '25 03:09

SCAND1UM


2 Answers

It looks to me like you want to run itertools.product on each sublist of your list of lists, and concatenate the results of that together.

Does the following do what you need?

import itertools

def combine(lists, min_length):
    items = []
    for start in range(len(lists)):
        for end in range(start + min_length, len(lists) + 1):
            items.extend(itertools.product(*lists[start:end]))
            
    return items

I called this function using the following:

combine([["a","b","c"],["d","e","f"],["g","h","i"]], 2)

and it returned a list of 45 tuples, which appeared to contain all of the items you are looking for.

like image 131
Luke Woodward Avatar answered Sep 08 '25 02:09

Luke Woodward


You have the first 27. Here is how you get the other 18:

import itertools as it
lst = [['a','b','c'],['d','e','f'],['g','h','i']]

result = [it.product(lst[i], lst[i+1]) for i in range(len(lst)-1)]
result = list(it.chain.from_iterable(result))

print(result)
#[('a', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('d', 'g'), ('d', 'h'), ('d', 'i'), ('e', 'g'), ('e', 'h'), ('e', 'i'), ('f', 'g'), ('f', 'h'), ('f', 'i')]
like image 24
pakpe Avatar answered Sep 08 '25 01:09

pakpe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!