简体   繁体   中英

Different combinations of a list with respect to a dictionary

Lets say I have a list

my_list = [a, b, c]

and a dictionary

my_dict = dict({a:a_prime, b:b_prime, c:c_prime})

where all letter, letter_prime are integers. How can I find all combinations of creating unique lists with respect to the dictionary? With my example above I'd like a function that takes [a,b,c], my_dict as input

  magic_function([a,b,c], my_dict)
  .
  .
  .

   return [[a_prime, b, c], [a, b_prime, c], [a, b, c_prime], [a_prime, b_prime, c], [a_prime, b, c_prime], [a, b_prime, c_prime], [a_prime, b_prime, c_prime]]

With unique im refeering too:

I consider [a_prime,b,c], [b,c, a_prime] to be equal, ie order doesnt mather.

And that it might be that some combinations are the same eg that [a_prime, b, c] turns out to be equal too [a, b_prime, c_prime]. It would be good then if only one of these are returned.

You can create all possible masks telling if we choose the key or corresponding value in the dict :

from itertools import product

my_dict = {'a': 'a_prime', 'b': 'b_prime', 'c': 'c_prime'}

def magic(keys):
    out = []
    for key_or_val in product([True, False], repeat=len(keys)):
        out.append([key if k_v else my_dict[key] for key, k_v in zip(keys, key_or_val)])
    return out

print(magic(['a', 'b', 'c']))
# [['a', 'b', 'c'], ['a', 'b', 'c_prime'], ['a', 'b_prime', 'c'], ['a', 'b_prime', 'c_prime'],
#  ['a_prime', 'b', 'c'], ['a_prime', 'b', 'c_prime'], ['a_prime', 'b_prime', 'c'],
# ['a_prime', 'b_prime', 'c_prime']]

If you only want unique values, just use a set:

uniques = set(tuple(combination) for combination in magic(['a', 'b', 'c']))

You can use recursion with a generator:

my_list = ['a', 'b', 'c']
def combos(d, c = []):
   if len(c) == len(my_list):
     yield c
   elif d:
     yield from combos(d[1:], c+[d[0]])
     yield from combos(d[1:], c+[f'{d[0]}_prime'])

print(list(combos(my_list)))

Output:

[['a', 'b', 'c'], ['a', 'b', 'c_prime'], ['a', 'b_prime', 'c'], ['a', 'b_prime', 'c_prime'], ['a_prime', 'b', 'c'], ['a_prime', 'b', 'c_prime'], ['a_prime', 'b_prime', 'c'], ['a_prime', 'b_prime', 'c_prime']]
my_list = ["a", "b", "c"]
my_dict = dict({"a": "a_prime", "b": "b_prime", "c": "c_prime"})

From the example above I noticed you don't want to have key value pairs in same output so we separate them by making collections. and when creating our collection we will choose either key or value for every possible combination.

my_coll = [[key, my_dict[key]] for key in my_list]

Output:
>> [['a', 'a_prime'], ['b', 'b_prime'], ['c', 'c_prime']]

Finally we can use itertools product to get the desrired output as mentioned by your example.

from itertools import product
combinations = [list(x) for x in product(*my_coll)]

Output:
>> [['a', 'b', 'c'], ['a', 'b', 'c_prime'], ['a', 'b_prime', 'c'], ['a', 'b_prime', 'c_prime'], ['a_prime', 'b', 'c'], ['a_prime', 'b', 'c_prime'], ['a_prime', 'b_prime', 'c'], ['a_prime', 'b_prime', 'c_prime']]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM