简体   繁体   中英

String manipulation in Python (All upper and lower case derivatives of a word)

I have to read in a word, and create an array which stores every variation of upper and lower case characters for this word in an array. For example with the word "abc". I need to find a way to retrieve every upper and lower case version of "abc" (abc, Abc, ABc, ABC, AbC, abC, and aBC). The string may also include numbers which should be left alone.

I know I would have to use recursion here in order to get every variation, but I'm just not quite sure how, or if there are any python libraries that provide this kind of operation.

Any help or tips is greatly appreciated!

from itertools import product
def randString(istr):
    l = [(c, c.upper()) if not c.isdigit() else (c,) for c in istr.lower()]
    return ["".join(item) for item in product(*l)]

print randString("aBC1")
print randString("A1b2c3")

Output

['abc1', 'abC1', 'aBc1', 'aBC1', 'Abc1', 'AbC1', 'ABc1', 'ABC1']
['a1b2c3', 'a1b2C3', 'a1B2c3', 'a1B2C3', 'A1b2c3', 'A1b2C3', 'A1B2c3', 'A1B2C3']

You can solve this using a Cartesian product . Given the string 'abc' , you'll want to split it into a list of possibilities in each position, eg:

['Aa', 'Bb', 'Cc']

I'll leave that to you, as it should be pretty easy. Once you've got that, you can use itertools.product to make all the combinations. You'll get an iterable of lists like

['A', 'b', 'C']

You can then use ''.join to join those lists together, getting your desired strings.

You can use product like this. The trick is to use sets to manage any characters that don't have distinct upper and lower versions (eg digits).

>>> from itertools import product
>>> [''.join(x) for x in product(*[{c.upper(), c.lower()} for c in "abc"])]
['ABC', 'ABc', 'AbC', 'Abc', 'aBC', 'aBc', 'abC', 'abc']
>>> [''.join(x) for x in product(*[{(c.upper(), c.lower()} for c in "abc1"])]
['ABC1', 'ABc1', 'AbC1', 'Abc1', 'aBC1', 'aBc1', 'abC1', 'abc1']

so

from itertools import product
def randString(s):
    return [[''.join(x) for x in product(*[{c.upper(), c.lower()} for c in s])]

You can make the output more consistent by shifting the .lower()

from itertools import product
def randString(s):
    return [[''.join(x) for x in product(*[{c.upper(), c} for c in s.lower()])]

Here is a solution using the good ol' recursion:

def get_all_variations(word):
    if len(word) == 1:
        #a single character has two variations. e.g. a -> [a, A]
        return [word, word.upper()]
    else:
        #otherwise, call recursively using the left and the right half, and merge results.
        word_mid_point = len(word) // 2
        left_vars = get_all_variations(word[:word_mid_point])
        right_vars = get_all_variations(word[word_mid_point:])
        variations = []
        for left_var in left_vars:
            for right_var in right_vars:
                variations.append(left_var + right_var)
        return variations

and

>>> get_all_variations("abc")
['abc', 'abC', 'aBc', 'aBC', 'Abc', 'AbC', 'ABc', 'ABC']

如果这不是家庭作业,则可以:

print(list(itertools.combinations('abcABC', 3)))

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