Home > Blockchain >  Best Way to Implement a Custom lower() method in Python
Best Way to Implement a Custom lower() method in Python

Time:08-15

I have an assignment where I'm not allowed to use the .lower() function so I'm creating my own. At the moment I have two ideas on how to do this but would love some input on what the most efficient way would be.

Method 1: Using if elif function

This is the most basic way I could think of, simply passing a character to the method and checking through each letter and returning its lowercase value. I thought this method might be quicker if I put the vowels higher up on the list as they occur the most:

def lowerCase(character):
    if character == "A":
        return 'a'
    elif character == "E":
        return 'e'

Method 2: Using two Lists:

The second idea I had was to have a list of capital letters and a corresponding list of lowercase letters and would return the index value of the lowecase array at the same position:

def lowerCase(character)

    lowercase_characters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
        'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
        'w', 'x', 'y', 'z'
    ]

    uppercase_characters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
        'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
        'W', 'X', 'Y', 'Z'
    ]

    for i in range(len(allowed_characters)-1):
        if character == uppercase_charactes[i]:
            return lowercase_characters[i]

I would love to know peoples thoughts on the most efficient way of doing this. Would it be quicker to go with method 2 and implement a quicksort algorithm or what would be the best way?

Thanks!

CodePudding user response:

Use ord to convert a character into its ASCII value, and chr to convert an ASCII value to its corresponding character. This allows you to translate a character from the uppercase range into the lowercase range just by adding and subtracting:

>>> def lower(char):
...     if 'A' <= char <= 'Z':
...         return chr(ord(char) - ord('A')   ord('a'))
...     else:
...         return char
...
>>> lower('R')
'r'
>>> lower('t')
't'

If you were going to implement it using a lookup table instead of doing ASCII algebra, the more efficient way to build the lookup table would be as a dict, since that gives you constant-time lookups:

>>> import string
>>> upper_to_lower = dict(zip(string.ascii_uppercase, string.ascii_lowercase))
>>> upper_to_lower
{'A': 'a', 'B': 'b', 'C': 'c', 'D': 'd', 'E': 'e', 'F': 'f', 'G': 'g', 'H': 'h', 'I': 'i', 'J': 'j', 'K': 'k', 'L': 'l', 'M': 'm', 'N': 'n', 'O': 'o', 'P': 'p', 'Q': 'q', 'R': 'r', 'S': 's', 'T': 't', 'U': 'u', 'V': 'v', 'W': 'w', 'X': 'x', 'Y': 'y', 'Z': 'z'}
>>> def lower(char):
...     return upper_to_lower.get(char, char)
...
>>> lower('R')
'r'

CodePudding user response:

As the lower() function deals with strings, it might be best to create a function which does the same. Conveniently all lower case letters are 32 ahead in the ASCII chart. This can be utilized in a simple function as follows:

def lower(s):
    # Holds the new string
    new_s = ""

    # Go through the string
    for i in s:

        # If it is upper case
        if "A" <= i <= "Z":

            # Change it to lower case and add it
            new_s  = chr(ord(i)   32)

        # If it is not upper case
        else:

            # Just add what it is
            new_s  = i

    # Return the new string
    return new_s

CodePudding user response:

You can take advantage of string methods. translate is efficient to perform character to character substitutions:

def lower(s):
    uc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    lc = 'abcdefghijklmnopqrstuvwxyz'
    table = str.maketrans(uc, lc)
    return s.translate(table)

lower('Abc DEF!')

Output: 'abc def!'

NB. To avoid typing the letters you can import strings.ascii_lowercase and strings.ascii_uppercase or use uc = ''.join([chr(x) for x in range(ord('A'), ord('Z') 1)]).

NB2. For efficiency, it would be better to define the translation table (with str.maketrans) outside of the function, so that it's not recomputed at each function call.

The advantage of translate is that you don't need to rely on a computation, you can predefine arbitrary substitutions. For example, if you wanted to replace each uppercase letter with the closest previous vowel:

def prev_vowel(s):
    c = 'BCDFGHJKLMNPQRSTVWXZ'
    v = 'AAAEEEIIIIIOOOOOUUUY'
    table = str.maketrans(c, v)
    return s.translate(table)

prev_vowel('ABC DEF!')
# 'AAA AEE!'
  • Related