liyuhao
liyuhao

Reputation: 375

How can I invert (swap) the case of each letter in a string?

I am learning Python and am working on this exercise:

Create a function that will return another string similar to the input string, but with its case inverted. For example, input of "Mr. Ed" will result in "mR. eD" as the output string.

My code is:

name = 'Mr.Ed'
name_list = []

for i in name:
    if i.isupper():
        name_list.append(i.lower())
    elif i.islower():
        name_list.append(i.upper())
    else:
        name_list.append(i)

    print(''.join(name_list))

Is there a simpler or more direct way to solve it?

Upvotes: 21

Views: 35665

Answers (8)

CristiFati
CristiFati

Reputation: 41147

Note: "Moved" the answer from [SO]: Python: Replace lower case to upper, and vice versa, simultaneously via ReGex lib (so more people can benefit out of it).

This is more like an exercise: I wanted to do a comparison between different variants (and apparently ReggaExp tends to be slower than string manipulations - and (as expected) swapcase is waaay faster than anything else).

code00.py:

#!/usr/bin/env python

import re
import string
import sys
import timeit


def swap_case_re(s):
    return re.sub(r"([A-Z]+)|([a-z]+)", lambda arg: arg.group(1).lower() if arg.group(1) else arg.group(2).upper(), s)


def swap_case_s0(s):
    return "".join(c.lower() if "A" <= c <= "Z" else c.upper() if "a" <= c <= "z" else c for c in s)


def swap_case_s1(s):
    return s.swapcase()


def swap_case_s2(s):
    return "".join(chr(c + 0x20 if 0x41 <= c <= 0x5A else c - 0x20 if 0x61 <= c <= 0x7A else c) for c in s.encode())


def swap_case_s3(s):
    return "".join(c.lower() if c.isupper() else c.upper() for c in s)


def swap_case_s4(s, tbl="".maketrans(string.ascii_uppercase + string.ascii_lowercase, string.ascii_lowercase + string.ascii_uppercase)):
    return s.translate(tbl)


FUCS = (
    swap_case_re,
    swap_case_s0,
    swap_case_s1,
    swap_case_s2,
    swap_case_s3,
    swap_case_s4,
)


def test_acc():
    print("Test accuracy:")
    for s in ("Www.GooGle.com",):
        for func in FUCS:
            print("{:s}({:s}): {:s}".format(func.__name__, s, func(s)))


def test_perf(count=1000000):
    print("\nTest performance:")
    for func in FUCS:
        print("{:s}: {:.3f}".format(func.__name__, timeit.timeit(lambda: func("Www.GooGle.com"), number=count)))


def main(*argv):
    test_acc()
    test_perf()


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.\n")
    sys.exit(rc)

Output (Win):

[cfati@CFATI-5510-0:e:\Work\Dev\StackExchange\StackOverflow\q076068146]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" ./code00.py
Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec  6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32

Test accuracy:
swap_case_re(Www.GooGle.com): wWW.gOOgLE.COM
swap_case_s0(Www.GooGle.com): wWW.gOOgLE.COM
swap_case_s1(Www.GooGle.com): wWW.gOOgLE.COM
swap_case_s2(Www.GooGle.com): wWW.gOOgLE.COM
swap_case_s3(Www.GooGle.com): wWW.gOOgLE.COM
swap_case_s4(Www.GooGle.com): wWW.gOOgLE.COM

Test performance:
swap_case_re: 5.039
swap_case_s0: 3.607
swap_case_s1: 0.315
swap_case_s2: 3.034
swap_case_s3: 2.700
swap_case_s4: 0.535

Done.

Upvotes: 0

krishna_mannava
krishna_mannava

Reputation: 1

The following program is for toggle case

name = input()
for i in name:
    if i.isupper():
        print(i.lower(), end='')
    else:
        print(i.upper(), end='')

Upvotes: 0

Shehreen Khan
Shehreen Khan

Reputation: 75

In python, an inbuilt function swapcase() is present which automatically converts the case of each and every letter. Even after entering the mixture of lowercase and uppercase letters it will handle it properly and return the answer as expected.

Here is my code:

str1 = input("enter str= ")
res = str1.swapcase()
print(res)

Upvotes: 4

Jorvis
Jorvis

Reputation: 386

Simply use the swapcase() method:

name = "Mr.Ed"
print(name.swapcase())

Output: mR.eD

Explanation:
The method swapcase() returns a copy of the string in which all the case-based characters have had their case swapped.

Upvotes: 16

wenzul
wenzul

Reputation: 4058

You can do that with name.swapcase(). Look up the string methods (or see the older docs for legacy Python 2).

Upvotes: 120

Prabal Tiwari
Prabal Tiwari

Reputation: 47

name='Mr.Ed'
print(name.swapcase())

Upvotes: 1

Surya Pratap
Surya Pratap

Reputation: 1

https://github.com/suryashekhawat/pythonExamples/blob/master/string_toggle.py

    def toggle(mystr):
        arr = []
        for char in mystr:
            if char.upper() != char:
                char=char.upper()
                arr.append(char)
            else:
                char=char.lower()
                arr.append(char)
        return ''.join(map(str,arr))
    user_input = raw_input()
    output = toggle(user_input)
    print output

Upvotes: 0

ch3ka
ch3ka

Reputation: 12158

Your solution is perfectly fine. You don't need three branches though, because str.upper() will return str when upper is not applicable anyway.

With generator expressions, this can be shortened to:

>>> name = 'Mr.Ed'
>>> ''.join(c.lower() if c.isupper() else c.upper() for c in name)
'mR.eD'

Upvotes: 26

Related Questions