Find all upper, lower and mixed case combinations of a string

I want to write a program that would take a string, let’s say "Fox", then it would display:

fox, Fox, fOx, foX, FOx, FoX, fOX, FOX

My code so far:

string = raw_input("Enter String: ")
length = len(string)
for i in range(0, length):
    for j in range(0, length):
        if i == j:
            x = string.replace(string[i], string[i].upper())
            print x

Output so far:

Enter String: fox
Fox
fOx
foX
>>> 

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

import itertools

s = 'Fox'
map(''.join, itertools.product(*zip(s.upper(), s.lower())))
>>> ['FOX', 'FOx', 'FoX', 'Fox', 'fOX', 'fOx', 'foX', 'fox']

Method 2

I always wanted to try this.

No idea if this fits your qualifications(it does work though).

str = raw_input()

def getBit(num, bit):
   return (num & 1 << bit) != 0

for i in xrange(0,2**len(str)):
   out = ""
   for bit in xrange(0,len(str)):
      if getBit(i,bit):
         out += str[bit].upper()
      else:
         out += str[bit].lower()

   print(out)

The idea is that as you increment in binary, you get every possible permutation of 1s and 0s.

Then you simply convert this list of 1s and 0s to a string, 1 meaning uppercase, 0 meaning lowercase.

Method 3

This is the excellent, accepted answer by @ephemient modified a little bit.

Changes:

  • lower-case before upper-case, just so the list starts with “fox” instead of “FOX” (the question’s example sequence starts with “fox”)
  • use of a list comprehension instead of map() (either way is fine, really)
  • broke out the code that generates the lower/upper case pairs to make it more clear
  • packaged it up into a function.

The code:

import itertools as it

def cap_permutations(s):
    lu_sequence = ((c.lower(), c.upper()) for c in s)
    return [''.join(x) for x in it.product(*lu_sequence)]

Method 4

One liner using list comprehension:

from itertools import permutations

strs='fox'
combin=[''.join(x) for x in permutations(list(strs)+list(strs.upper()),3) if ''.join(x).lower()=='fox']
print(combin)
>>> ['fox', 'foX', 'fOx', 'fOX', 'Fox', 'FoX', 'FOx', 'FOX']

Using a for loop:

from itertools import permutations

strs='fox'
lis2=list(strs)+list(strs.upper())

for x in permutations(lis2,3):
    if ''.join(x).lower()=='fox':
        print(''.join(x))

>>> fox
    foX
    fOx
    fOX
    Fox
    FoX
    FOx
    FOX

Method 5

Use product (False, True) to find any permutations of change char in string for upper & lower:

def capitalize_char_permutation (string:str) -> str :
    conditions = product((0,1), repeat=len(string))
    for i in conditions:
        result = ''
        for j in range(len(i)):
            if i[j]==0 :
                result+= string[j].lower()
            else:
                result+= string[j].upper()
        yield result

Method 6

Although what I tried is in c++, I guess you will get the logic. I was stuck in the same question so I searched around and this is what I ended up writing…I know it is not perfect and I would love if someone helps me make this code better and point out my mistakes.

#include <bits/stdc++.h>

using namespace std;

string decToBinary(int n,int l) 
{ 
    string ret="";
    for (int i = l-1; i >= 0; i--) { 
        int k = n >> i; 
        if (k & 1) 
            ret=ret+"1"; 
        else
            ret=ret+"0";
    }
    return ret; 
}

int main()
{
    string x;
    cin>>x;
    transform(x.begin(), x.end(), x.begin(), ::tolower); 
    int size=x.length();
    string bin;
    for(int i=0;i<pow(2,size);i++)
    {
        bin=decToBinary(i,size);
        for(int j=0;j<size;j++)
        {
            if(bin[j]=='1')
                cout<<(char)(x[j]-32);
            else
                cout<<x[j];
        }
        cout<<endl;
    }
}

Suppose the word “dog”…so, there will be 2^(number of letters) i.e. 2^3=8 combination. So, in this program, we iterate from 0-7 and convert the iterator(i in this case) to binary, for example, take the fifth iteration the binary would be 101 then the resultant word would be DoG (taking 1 as upper case and 0 as the lower case)..like this you can get all 2^n resultant words.

Method 7

I combined @ephemient’s solution, @steveha’s solution, and my own tweak.

def allcasecombinations(s):
    return list({''.join(x) for x in itertools.product(*zip(s.upper(), s.lower()))})

my improvement is using a set and then converting it to a list. the set is to remove duplicates: for example if your string had punctuation, the original function would have duplicates (because " ".upper() == " ".lower()). I incorporated @steveha’s work cause I figured using list comprehension inside a set is cleaner than list(set(map(itertoolsmagic))). the list conversion probably isn’t necessary for most use cases, but I added it to be safe.

>>> allcasecombinations("hi!")
['HI!', 'hI!', 'Hi!', 'hi!']


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x