Search code examples
pythoncombinations

How do you get 'additional' combinations when adding items to a list that I have already gotten all combinations for?


Using python I would like to calculate all combinations of 3 from a list.

For example, list = [a,b,c,d] and combinations would be - [a,b,c], [a,b,d], [a,c,d], [b,c,d].

And then I would like to add some items to the original list and get only the additional combinations of 3.

For example, adding items [e,f] would generate new combinations - [a,b,e], [a,b,f], [a,c,e], [a,c,f], [a,d,e], [a,d,f], [a,e,f], [b,c,e], [b,c,f],...

The lists will be large so we need to avoid generating the combinations twice and then filtering in order to get the 'additional combinations'.

Background: I use itertools.combinations to get all combinations (of 3) for a list right now of about 100 items. That generates a lot of combinations and I doing a bunch of calculations and whatnot based on those combinations, looking for patterns and matches and stuff. I get through all that processing and if I don't have a 'successful' combination of 3 then I generate more candidates for the list (which in itself takes a long time). When I add the additional candidates to the list (usually like 10 or so), I then restart the analysis on the combinations which seems wasteful, so I would like to only be checking the 'additional' combinations.


Solution

  • Add the new items one by one:

    from itertools import combinations
    
    old = ['a', 'b', 'c', 'd']
    new = ['e', 'f']
    
    for item in new:
        for comb in combinations(old, 2):
            print(*comb, item)
        old.append(item)
    

    Output (Attempt This Online!):

    a b e
    a c e
    a d e
    b c e
    b d e
    c d e
    a b f
    a c f
    a d f
    a e f
    b c f
    b d f
    b e f
    c d f
    c e f
    d e f
    

    Or if order within each combination doesn't matter (inspired by a comment):

    from math import comb
    from itertools import combinations, islice
    
    old = ['a', 'b', 'c', 'd']
    new = ['e', 'f']
    
    new_combs = comb(len(old) + len(new), 3) - comb(len(old), 3)
    for comb in islice(combinations(new + old, 3), new_combs):
        print(*comb)
    

    Output (Attempt This Online!):

    e f a
    e f b
    e f c
    e f d
    e a b
    e a c
    e a d
    e b c
    e b d
    e c d
    f a b
    f a c
    f a d
    f b c
    f b d
    f c d