Search code examples
pythonlistcombinations

Combining similar lists


I have these lists:

{'HH1': ['x'], 'HH2': ['y', 'x'], 'HH3': ['x', 'z'], 'HH4': ['x'], 'HH5': ['x'], 'HH6': ['x'], 'HH7': ['x'], 'HH8': ['x', 'y', 'z'], 'HH9': ['x'], 'HH10': ['x', 'y'], 'HH11': ['x'], 'HH12': ['x'], 'HH13': ['x'], 'HH14': ['x'], 'HH15': ['x', 'y'], 'HH16': ['x', 'y'], 'HH17': ['x', 'y'], 'HH18': ['x']}

I want to iterate through them to:

  1. Count the number (i) of similar combinations
  2. Create a new list with each combination, named: n=i

The output should be:

n=11: ('x')
n=5: ('x', 'y')
n=1: ('x', 'z')
n=1: ('x', 'y', 'z')

I can't seem to get it right.

**1. **I tried this, but then it skips a combination (n=1: ('x', 'z')).

from collections import Counter
from itertools import combinations

# Counting occurrences of each combination of fuel types
combination_count = Counter()
unique_combinations = set()
for fuel_list in hfuels.values():
    for r in range(1, len(fuel_list) + 1):
        for combination in combinations(fuel_list, r):
            unique_combinations.add(tuple(sorted(combination)))

# Creating new lists for each combination
renamed_lists = {}
for combination in unique_combinations:
    count = sum(1 for fuel_list in hfuels.values() if set(combination) == set(fuel_list))
    if count:
        renamed_lists[f"n={count}"] = list(combination)

# Printing the renamed lists
for name, fuel_list in renamed_lists.items():
    print(f"{name}: {fuel_list}")
**Outcome:**
n=1: \['z', 'y', 'x'\]
n=5: \['y', 'x'\]
n=11: \['x'\]

**2. **I also tried this, but then it count the occurrences rather than combinations.

from collections import Counter from itertools import combinations

# Counting occurrences of each combination of fuel types
combination_count = Counter()
unique_combinations = set()
for fuel_list in hfuels.values():
    for r in range(1, len(fuel_list) + 1):
        for combination in combinations(fuel_list, r):
            combination_count[tuple(sorted(combination))] += 1
            unique_combinations.add(tuple(sorted(combination)))

# Creating new lists for each combination
renamed_lists = {}
for combination in unique_combinations:
    count = combination_count[combination]
    if count:
        renamed_lists[f"n={count}"] = list(combination)

# Printing the renamed lists
for name, fuel_list in renamed_lists.items():
    print(f"{name}: {fuel_list}")

Outcome:

n=1: \['z', 'y', 'x'\]
n=2: \['z'\]
n=6: \['y'\]
n=18: \['x'\]

Solution

  • Your issue is that the keys must be unique in a dictionary (which is what you're using, not a list), so you can't have two (or more) values with the same 'n=1' key. If you use the lists as the keys, then you can use the values to count occurences.

    Something like

    HH_dict = {'HH1': ['x'], 'HH2': ['y', 'x'], ... }
    unique = {}
    for element in HH_dict:
        elem_tuple = tuple(sorted(HH_dict[element]))
        if elem_tuple not in unique.keys():
            unique[elem_tuple] = 1
        else:
            unique[elem_tuple] += 1
    for key, value in sorted(unique.items(), key=lambda item: item[1], reverse=True):
        print(f"n={value}: {key}")
    

    would work to print the output you're looking for.