How to separate uppercase and lowercase letters in a string?

Question:

I have written code that separates the characters at ‘even’ and ‘odd’ indices, and I would like to modify it so that it separates characters by upper/lower case.

I can’t figure out how to do this for a string such as "AbBZxYp". I have tried using .lower and .upper but I think I’m using them incorrectly.

def upperLower(string):
    odds=""
    evens=""
    for index in range(len(string)):
        if index % 2 == 0:
            evens = evens + string[index]
        if not (index % 2 == 0):
            odds = odds + string[index]
    print "Odds: ", odds
    print "Evens: ", evens
Asked By: Rocko 1234

||

Answers:

Are you looking to get two strings, one with all the uppercase letters and another with all the lowercase letters? Below is a function that will return two strings, the upper then the lowercase:

def split_upper_lower(input):
    upper = ''.join([x for x in input if x.isupper()])
    lower = ''.join([x for x in input if x.islower()])

    return upper, lower

You can then call it with the following:

upper, lower = split_upper_lower('AbBZxYp')

which gives you two variables, upper and lower. Use them as necessary.

Answered By: berto
>>> filter(str.isupper, "AbBZxYp")
'ABZY'
>>> filter(str.islower, "AbBZxYp")
'bxp'

Btw, for odd/even index you could just do this:

>>> "AbBZxYp"[::2]
'ABxp'
>>> "AbBZxYp"[1::2]
'bZY'
Answered By: Stefan Pochmann

There is an itertools recipe called partition that can do this. Here is the implementation:

From itertools recipes:

def partition(pred, iterable):
    'Use a predicate to partition entries into false entries and true entries'
    # partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
    t1, t2 = tee(iterable)
    return filterfalse(pred, t1), filter(pred, t2)

Upper and Lowercase Letters

You can manually implement the latter recipe, or install a library that implements it for you, e.g. pip install more_itertools:

import more_itertools as mit


iterable = "AbBZxYp"
pred = lambda x: x.islower()

children = mit.partition(pred, iterable)
[list(c) for c in children]
# [['A', 'B', 'Z', 'Y'], ['b', 'x', 'p']]

Here partition uses a predicate function to determine if each item in an iterable is lowercase. If not, it is filtered into the false group. Otherwise, it is filtered into the group of true items. We iterate to expose these groups.


Even and Odd Indices

You can modify this to work for odd and even indices as well:

import itertools as it

import more_itertools as mit


iterable = "AbBZxYp"
pred = lambda x: x[0] % 2 != 0

children = mit.partition(pred, tuple(zip(it.count(), iterable)))
[[i[1] for i in list(c)] for c in children]
# [['A', 'B', 'x', 'p'], ['b', 'Z', 'Y']]

Here we zip an itertools.count() object to enumerate the iterable. Then we iterate the children so that the sub items yield the letters only.

See also more_itertools docs for more tools.

Answered By: pylang
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.