Понимание функции, которая находит самый длинный ключ в словаре - PullRequest
0 голосов
/ 08 ноября 2018

Метод find_longest в следующем классе dict находит самое длинное значение ключа в словаре.

class LongestKey(dict):
    def find_longest(self):
        longest = None
        for key in self:
            if not longest or len(key) > len(longest):
                longest = key
        print(key)

a = LongestKey()
a["hi"] = 1
a["hello"] = 2
a["hey there"] = 3
a["greetings sir"] = 4

a.find_longest()

Код работает, но мне очень трудно разобраться в логикеесли нет или заявление.Первоначально я использовал

if len(key) > len(longest):

вместо

if not longest or len(key) > len(longest):

, но выдает ошибку: TypeError: object of type 'NoneType' has no len().Почему это?Большое спасибо за то, что просветили меня в этом.

Ответы [ 5 ]

0 голосов
/ 08 ноября 2018

Когда вы делаете:

longest=None

Вы убедитесь, что объект самый длинный имеет ' без значения ' или ' пустое значение '. В Python нам не нужно сначала объявлять переменные, поэтому в Python действительно нет пустых переменных. Установка переменной Нет - это не то же самое, что установка для нее пустого значения по умолчанию; Ничто не является значением, хотя оно часто используется, чтобы сигнализировать пустота . Итак, как вы можете посчитать длину объекта, если он пуст? Вот логика, используемая здесь: longest вообще не имеет никакого значения, поэтому выдает ошибку:

TypeError: object of type 'NoneType' has no len()

А когда вы используете:

if not longest or len(key) > len(longest):

Вы убедитесь, что объект самый длинный не имеет значения Нет .

0 голосов
/ 08 ноября 2018

Это предотвращает возникновение ошибки во время первой итерации цикла for.

Часть логического выражения not longest вычисляется первой, и если она равна True, то остаток выражения - часть or len(key) > len(longest) - не будет оцениваться, и значение всего выражения также будет True.

Это необходимо, потому что изначально longest был установлен на None, и запись логического выражения таким образом предотвращает оценку части len(longest) второй половины и происходит TypeError, поскольку longest не имеет длина еще.

0 голосов
/ 08 ноября 2018

Сначала вы объявляете переменную longest и присваиваете ей None

def find_longest(self):
    longest = None  

NoneType не имеет len(). Так что привести к этому утверждению:

if not longest or len(key) > len(longest):
...

Проверяет, был ли longest обновлен или нет

0 голосов
/ 08 ноября 2018

Зачем вам нужна проверка if not longest, потому что при первом запуске цикла longest равен None, а вы не можете выполнить len(None). Таким образом, вы делаете if not longest проверку, и только если это False, проверяется второе условие.


Этой дополнительной проверки в этом случае можно избежать, инициализируя longest до -1 вместо None и сравнивая len(key) с longest (не len(longest)).

Примерно так:

class LongestKey(dict):    
    def find_longest(self):
        longest = -1  
        for key in self:
            if len(key) > longest:
                longest = len(key)
                longest_key = key
        print(longest_key)   # <-- print longest key not just key.

Примечание : Ваш код печатает только последнюю клавишу, которая может быть не самой длинной клавишей каждый раз. В if вам необходимо обновить самый длинный ключ вместе со значением longest, как показано.

0 голосов
/ 08 ноября 2018

Это потому, что вы проверяете длину longest, которая установлена ​​на None. Отсюда и ошибка.

Пример,

x = None
print(len(x))

# output
TypeError: object of type 'NoneType' has no len()

Причина, по которой вы не получаете сообщение об ошибке, заключается в том, что if not longest выполняется, а второе условие len(key) > len(longest) даже не выполняется, потому что первое уже найдено. Кроме того, причина, по которой он работает, заключается в том, что значение longest изменяется на второй итерации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...