1

How to get all possible combination of cases as well as letters for a string in python?

Example

input:'ab' output:aB', 'Ba', 'BA', 'Ab', 'AB', 'bA'

input : 'dan' output:aND', 'ANd', 'Dna', 'naD', 'DaN', 'aDn', 'Adn', 'dnA', 'NdA', 'anD', 'DnA', 'NAD', 'nAD', 'Dan', 'NDA', 'nAd', 'AdN', 'DAn', 'AnD', 'And', 'DNA', 'daN', 'adN', 'nDa', 'dAN', 'dNa', 'aDN', 'ADN', 'dNA', 'Nda', 'AND', 'DNa', 'NaD', 'Nad', 'aNd', 'nDA', 'dAn', 'NAd', 'ndA', 'NDa', 'ADn', 'DAN'

  • I don't think this is a duplicate of the first, because it includes case; or the second, because it includes more than simply case. But I admit I don't understand why the all-lowercase outputs seem to be excluded, so I must be missing something. – DSM May 20 '14 at 02:58

3 Answers3

1

This can be done using itertools

from itertools import permutations
def perm(word):
    perms = [''.join(p) for p in permutations(word)]
    print(perms)
    return perms

def capPer(arrPerm):
    result=[]
    for val in arrPerm:
        wordList=list(val)

        for i,letter in enumerate(wordList):
            wordList[i]=letter.upper()
            result.extend(perm(''.join(wordList)))
    return set(result)

def combi(wrd):
    print(capPer(perm(wrd)))


combi('ab')
combi('dan')

**output:**
set(['aB', 'Ba', 'BA', 'Ab', 'AB', 'bA'])
set(['aND', 'ANd', 'Dna', 'naD', 'DaN', 'aDn', 'Adn', 'dnA', 'NdA', 'anD', 'DnA', 'NAD', 'nAD', 'Dan', 'NDA', 'nAd', 'AdN', 'DAn', 'AnD', 'And', 'DNA', 'daN', 'adN', 'nDa', 'dAN', 'dNa', 'aDN', 'ADN', 'dNA', 'Nda', 'AND', 'DNa', 'NaD', 'Nad', 'aNd', 'nDA', 'dAn', 'NAd', 'ndA', 'NDa', 'ADn', 'DAN'])
YBathia
  • 894
  • 1
  • 8
  • 18
1

You could do it with the itertools.product function. Read about it at https://docs.python.org/2/library/itertools.html

here's an example:

def combos(s):
    combolist = []
    for i in range(len(s)):
        combolist.append([])
    for i in range(len(s)):
        combolist[i].append(s[i].lower())
        combolist[i].append(s[i].upper())
    return list(itertools.product(*combolist))

With output:

combos('ab')
>>> [('a', 'b'), ('a', 'B'), ('A', 'b'), ('A', 'B')]
combos('dan')
>>> [('d', 'a', 'n'), ('d', 'a', 'N'), ('d', 'A', 'n'), ('d', 'A', 'N'), ('D', 'a', 'n'), ('D', 'a', 'N'), ('D', 'A', 'n'), ('D', 'A', 'N')]

can easily format from there.

Tyler McAtee
  • 300
  • 2
  • 12
1

Combining itertools.permutations and itertools.product:

from itertools import permutations, product

def perm_with_case(word):
    cased = product(*zip(word.lower(), word.upper()))
    next(cased) # throw away the all-lowercase result
    return (''.join(p) for w in cased for p in permutations(w))

gives

>>> list(perm_with_case("ab"))
['aB', 'Ba', 'Ab', 'bA', 'AB', 'BA']
>>> list(perm_with_case("dan"))
['daN', 'dNa', 'adN', 'aNd', 'Nda', 'Nad', 'dAn', 'dnA', 'Adn', 'And', 'ndA', 'nAd', 'dAN', 'dNA', 'AdN', 'ANd', 'NdA', 'NAd', 'Dan', 'Dna', 'aDn', 'anD', 'nDa', 'naD', 'DaN', 'DNa', 'aDN', 'aND', 'NDa', 'NaD', 'DAn', 'DnA', 'ADn', 'AnD', 'nDA', 'nAD', 'DAN', 'DNA', 'ADN', 'AND', 'NDA', 'NAD']

which seems to match the desired output, although I admit I don't see why we're tossing the all-lowercase values.

DSM
  • 342,061
  • 65
  • 592
  • 494