Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate all combinations of a set of characters without repetitions?

I have the following list:

['a', 'b', 'c']

I'm looking into a way to generate all possible strings that contain these characters with the following restrictions:

  • a character may not occur multiple times (aab, aba, abca etc. is invalid)
  • a character may be excluded (ab is valid even if c is not present; a is also valid even if b and c are not present)

I can use

[''.join(p) for p in permutations('abc')]

to generate all strings that contain a, b and c. However I have to also do

[''.join(p) for p in permutations('ab')]
[''.join(p) for p in permutations('ac')]
[''.join(p) for p in permutations('bc')]

As you can probably tell if the initial list of available characters is long I need to do a lot of work. So I'm looking for an elegant way in Python to generate all of the above with just the list of allowed characters as input:

def generate(vals=['a', 'b', 'c']):
  # The initial list of allowed characters also has to be part of the 
  # final list since these also represent valid values
  res = vals
  # Generate all possible strings and store in res

  return res

I need this since I want to provide a parameter for a POST request for my web server, where a parameter (let's call it val) can take different unique values (either single characters or a combination of those) in order to trigger some data generation. The list of available values will grow over time so I'd like to make it easier to process the request by automating the check if the given values for val is a valid one.

I've been also thinking of iterating through each element of the list of allowed characters and concatenating it the rest ('a', 'ab', 'ac', 'abc', 'b', 'ba', 'bc' etc.) but I have no idea how to do that.

like image 529
rbaleksandar Avatar asked Mar 01 '18 15:03

rbaleksandar


People also ask

How do you generate all possible combinations of one list?

Enter the formula =List1. Expand out the new List1 column and then Close & Load the query to a table. The table will have all the combinations of items from both lists and we saved on making a custom column in List1 and avoided using a merge query altogether!

How do you figure out combinations of a set of characters?

The exact formula is: =COMBIN(universe, sets). The number of four-character combinations that can be made from the alphabet is: =COMBIN(26, 4) or 14,950.

How many combinations can you make with 3 numbers without repeating?

There are 504 different 3-digit numbers which can be formed from numbers 1, 2, 3, 4, 5, 6, 7, 8, 9 if no repetition is allowed. Note: We can also use the multiplication principle to answer this question.


2 Answers

I would chain different permutations of the string characters with a length constraint:

import itertools

def generate(vals="abc"):
    return ("".join(x) for x in itertools.chain.from_iterable(itertools.permutations(vals,i+1) for i in range(0,len(vals))))

print(list(generate("abc"))) # force iteration to print result

result:

['a', 'b', 'c', 'ab', 'ac', 'ba', 'bc', 'ca', 'cb', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba']

Edit: seems that I produced a variant of the powerset recipe (what's a good way to combinate through a set?), not considering the empty string, considering order of the characters (abc and cba are 2 different items) and using str.join to generate strings directly.

like image 32
Jean-François Fabre Avatar answered Oct 09 '22 09:10

Jean-François Fabre


There are correct answers already been posted but I wanted to give it a shot, made it as readable as I can.

from itertools import permutations as p

def gen(lst):
    y = [[a for a in p(lst,y)] for y in range(1,len(lst)+1)]

    this = []
    for i in y:
        while len(i)>0:
            this.append(i.pop())
    return [''.join(x) for x in this]

print(gen(['a','b','c']))
like image 126
Işık Kaplan Avatar answered Oct 09 '22 08:10

Işık Kaplan