Сортировка строки с помощью функции ord - PullRequest
1 голос
/ 24 апреля 2020

Я пытаюсь разбить строку, используя функцию ord. Это мой код

def sortString(info):
    res = isinstance(info, str)
    if res:
        for char in info:
            charValue = ord(char)

            #Lowercase
            if charValue > 96 and charValue < 123:
                lChar += char

            #Uppercase   
            elif charValue > 64 and charValue < 91:
                cChar += char

            #Punctuation
            elif charValue > 32 and charValue < 65:
                pChar += char

            #Spaces
            elif charValue == 32:
                numSpace += 1

        result = "cChar\nlChar\npChar\nnumSpace"

        return result
    else:
        return "Not a string!"

Я хочу разделить строку на верхний, нижний регистр, знаки пунктуации и количество пробелов. Так что "Привет, мир!" выдаст:

HW  
elloorld   
,!!  
1

Ошибка, которую я получаю сейчас, - UnboundLocalError: локальная переменная 'cChar', на которую ссылается перед присваиванием. Я пытался создать пустую строку, но это не решило проблему.

Ответы [ 3 ]

3 голосов
/ 24 апреля 2020

Вы обновляете cChar перед его инициализацией, а также lChar и pChar

def sortString(info):
    res = isinstance(info, str)
    if res:
        # INITIALISING
        cChar = lChar = pChar = "" #initialisation error fixed
        numSpace = 0 #initialisation error fixed
        for char in info:
            charValue = ord(char)

            #Lowercase
            if charValue > 96 and charValue < 123:
                lChar += char #initialisation error

            #Uppercase   
            elif charValue > 64 and charValue < 91:
                cChar += char #initialisation error

            #Punctuation
            elif charValue > 32 and charValue < 65:
                pChar += char #initialisation error

            #Spaces
            elif charValue == 32:
                numSpace += 1 #initialisation error

        result = cChar+ '\n' + lChar + '\n' +pChar + '\n' +str(numSpace) # indentation error and value error
        # you can also use this 
        # result = f"{cChar}\n{lChar}\n{pChar}\n{numSpace}" 
        return result #indentation error
    else:
        return "Not a string!"

print(sortString("HelloWhatsup"))

Пожалуйста, обновите ваш код, в котором есть ошибки

1 голос
/ 24 апреля 2020

Создание cChar пустой строки решает проблему. Тем не менее, lChar, pChar и numSpace также должны быть определены.

Тогда есть еще две проблемы: строки result = и return имеют слишком большой отступ, и ваши result не использует переменные.

Итак, чтобы исправить это:

cChar = lChar = pChar = ''
numSpace = 0
for char in info:
    # ...
result = '\n'.join([cChar, lChar, pChar, str(numSpace)])
return result

Кстати, есть много вещей, которые вы могли бы улучшить. Для начала:

Используйте охранные предложения вместо вложенных условных выражений и используйте исключения для сообщений об ошибках

if not isinstance(info, str):
    raise TypeError("Not a string!")

Используйте Python синтаксис проверки интервала

if 96 < charValue < 123:  # Lowercase
    lChar += char
0 голосов
/ 25 апреля 2020

Поскольку регулярные выражения являются медленными (?)

Если обоснование использования ord() и диапазона тестирования заключается в том, чтобы попытаться избежать медлительности регулярных выражений, то вы собираетесь разочароваться.

Давайте сравним решение регулярного выражения с sortString(), подходом, использующим ord() и тестирование диапазона, для группировки символов.

Подход регулярного выражения

Регулярные выражения используются для сопоставления нескольких групп диапазонов символов, а zip() для объединения совпадений в списки групп.

>>> import re
>>> expr = re.compile(r"""([A-Z]+)  |         # Capitals.
...                       ([a-z]+)  |         # Lowercase.
...                       (\s+)     |         # Whitespace.
...                       ([!-/:-@\[-`{-~]+)  # Punctuation and symbols.
...                       """, 
...                       re.VERBOSE)
...
>>> [''.join(m) for m in zip(*expr.findall("The quick, and brown, fox"
...                                        " jumped (not leaped) over"
...                                        " the LAZY!!! dog =(."))]
['TLAZY', 
 'hequickandbrownfoxjumpednotleapedoverthedog', 
 '            ', 
 ',,()!!!=(.']

Синхронизация с рабочей реализацией для sortString() в другие ответы, я получаю почти то же самое время для выполнения 10 ** 6 итераций.

>>> timeit.timeit("group_chars_regex(s)", globals=globals(), number=10**6)
16.637040594941936

Работа на виртуальной машине Linux на хосте Ma c, которому более 10 лет.

Подход к словарю

Быстрый поиск по словарю, давайте рассчитывать решение на основе словаря, которое выполняет группировки.

>>> groups = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
...           "abcdefghijklmnopqrstuvwxyz",
...           " \t\r\n",
...           "!@#$%^&*()_+=-`~,..;:/?'\"[]{}\|")
>>> group_dict = {ch: n for n in range(4) for ch in groups[n]}
>>> 
>>> def group_chars(s):
...     lis = ['', '', '', '']
...     for ch in s:
...         lis[group_dict[ch]] += ch
...     return lis

group_dict карты каждой ча к индексу группы, к которой он принадлежит. Этот индекс используется для обновления строк в списке.

Сравнивая его с sortString(), мы видим, что время сбрасывается на 4 с.

>>> timeit.timeit("group_chars(s)", globals=globals(), number=10**6)
12.557713539921679
>>>
>>> # The ord() and range testing method:
>>> timeit.timeit("sortString(s)", globals=globals(), number=10**6)
16.32978364895098
>>> 

Подход dict - это Самый быстрый из трех способов группировки.

...