简体   繁体   中英

Python permutations skipping duplicates

My problem is: I have a list of values

model = ["AT","V","AP","RH"]

and I want to generate their permutations without duplicates.

A permutation in this case for me is eg

["AT"]
["V"]
["AP"]
["RH"]
["AT","V"]
["AT","AP"]
....
["AT","V","AP"]
["AT","V","RH"]
....
["AT","V","AP","RH"]

without duplicates in this case means, the order doesn't matter for me

["AT","V"] == ["V","AT"] is the same for me
["AT","V","AP","RH"] == ["RH","AT","V","AP"] == ["AP","RH","AT","V"] is the same for me

Any idea how I can reach my goal a smart way?

I found some solutions eg itertools.permutations but it didn't actually work for me as it doesn't consider my wish to ignore "duplicates"

You can use itertools.chain.from_iterable with itertools.combinations . itertools.combinations will generate all combinations of a given size. To get all the desired combinations, we iterate over all possible sizes. Then, we use itertools.chain.from_iterable , which will collect all of the combinations into one flattened iterable:

list(chain.from_iterable(combinations(model, i) for i in range(1, len(model) + 1)))

This outputs:

[('AT',), ('V',), ('AP',), ('RH',),
...
('AT', 'AP', 'RH'), ('V', 'AP', 'RH'), ('AT', 'V', 'AP', 'RH')]
from more_itertools import powerset

list(powerset(["AT","V","AP","RH"]))

#[(),
 ('AT',),
 ('V',),
 ('AP',),
 ('RH',),
 ('AT', 'V'),
 ('AT', 'AP'),
 ('AT', 'RH'),
 ('V', 'AP'),
 ('V', 'RH'),
 ('AP', 'RH'),
 ('AT', 'V', 'AP'),
 ('AT', 'V', 'RH'),
 ('AT', 'AP', 'RH'),
 ('V', 'AP', 'RH'),
 ('AT', 'V', 'AP', 'RH')]

[list(x) for x in powerset(["AT","V","AP","RH"])][1:]  # omitting the blank value

[['AT'],
 ['V'],
 ['AP'],
 ['RH'],
 ['AT', 'V'],
 ['AT', 'AP'],
 ['AT', 'RH'],
 ['V', 'AP'],
 ['V', 'RH'],
 ['AP', 'RH'],
 ['AT', 'V', 'AP'],
 ['AT', 'V', 'RH'],
 ['AT', 'AP', 'RH'],
 ['V', 'AP', 'RH'],
 ['AT', 'V', 'AP', 'RH']]

I think you want itertools.combinations instead of itertools.permutations .

permutations(p[, r])
  r-length tuples, all possible orderings, no repeated elements

combinations(p, r)
  r-length tuples, in sorted order, no repeated elements

Here is an example:

import itertools


def combos(elements):
    return [
        combo
        for i in range(len(elements))
        for combo in itertools.combinations(elements, i + 1)
    ]


model = ["AT", "V", "AP", "RH"]


combos(model)

# [('AT',),
#  ('V',),
#  ('AP',),
#  ('RH',),
#  ('AT', 'V'),
#  ('AT', 'AP'),
#  ('AT', 'RH'),
#  ('V', 'AP'),
#  ('V', 'RH'),
#  ('AP', 'RH'),
#  ('AT', 'V', 'AP'),
#  ('AT', 'V', 'RH'),
#  ('AT', 'AP', 'RH'),
#  ('V', 'AP', 'RH'),
#  ('AT', 'V', 'AP', 'RH')]

https://docs.python.org/3/library/itertools.html#itertools.combinations

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