Как я могу получить этот код для возврата неповторимого письма? Вместо этого он дает KeyError

def nonDuplicate(string):

    hashTable = {}

    for i in string:
        if hashTable[i]:
            return i
        else:
            hashTable[i] = True

print(nonDuplicate('minimum'))

Это должно вернуть 'n', однако я продолжаю получать KeyError для первого элемента. Что мне не хватает?

0
Vellutante 3 Май 2021 в 01:15

3 ответа

Лучший ответ

Если i не входит в hashTable, вы получите KeyError. Это не похоже на некоторые другие языки, такие как JavaScript, где вы получаете undefined, что является ложным (Boolean(undefined) === false).

Вместо этого вы можете проверить, находится ли i в hashTable, поскольку на самом деле не имеет значения, если это True, пока оно присутствует.

if i in hashTable:

Однако ваш код на самом деле не работает. На выходе получается 'i'. Вам нужно прочитать всю строку, чтобы найти неповторяющиеся символы. Я рекомендую использовать Counter:

def nonDuplicate(string):
    from collections import Counter
    c = Counter(string)
    for x, count in c.items():
        if count == 1:
            return x

print(nonDuplicate('minimum'))  # -> n

Примечание. Если вы используете Python 3.6 или более ранней версии, это может вернуть 'u' вместо 'n', поскольку dicts weren не обязательно сохранение порядка.

3
wjandrea 2 Май 2021 в 22:44

KeyError вызывается оператором if, потому что первой буквы 'm' нет в словаре, но вы пытаетесь получить ее значение. Правильный подход - вызвать hashTable.get(i) или более питонический способ проверки if i in hashTable:

Хотя это решит KeyError, я боюсь, что это не сработает правильно для поиска не повторяющегося символа. Для этого вам нужно будет пройти всю строку и вернуть символы с ровно 1 вхождением.

2
wjandrea 2 Май 2021 в 22:31

Вместо этого вы можете использовать get, который вернет None, если ключ не существует (вместо того, чтобы поднимать KeyError).

if hashTable.get(i):

Чтобы явно указать, что значение по умолчанию - False, вы можете передать второй аргумент (как предлагает wjandrea):

if hashTable.get(i, False):
2
iota 2 Май 2021 в 22:33