Понимание Dict не работает, как я думал. Что я делаю неправильно?

Понимание Dict с условием if-else, похоже, вообще не использует блок if. Он всегда переходит в блок else, даже если не должен.

Я пытаюсь использовать понимание dict с условием if в python, чтобы определить количество вхождений символов в строку. Однако условие if никогда не кажется выполненным (когда оно действительно должно быть выполнено). Кажется, что выполнено только условие else

def letter_count(input_str):
    letter_count_map = {}

    letter_count_map = {letter: letter_count_map[letter]+1 if letter in 
                        letter_count_map.keys() else 1 
                        for letter in input_str}
    print(letter_count_map)


letter_count("serendipity")

Ожидаемый результат:

{'s': 1, 'e': 2, 'r': 1, 'n': 1, 'd': 1, 'i': 2, 'p': 1, 't': 1, 'y': 1}

Фактический результат:

{'s': 1, 'e': 1, 'r': 1, 'n': 1, 'd': 1, 'i': 1, 'p': 1, 't': 1, 'y': 1}

Что я делаю неправильно?

@pylang Спасибо за указатель. Проверим.

Gopinath Taget 30.05.2019 07:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

letter_count_map не присваивается новое значение до тех пор, пока понимание dict не будет полностью оценено. До того, как это произойдет, это просто пустой dict, и поэтому в его keys() ничего не будет. То, что вы пытаетесь сделать, должно выполняться с помощью цикла вместо понимания:

letter_count_map = {}
for letter in input_str:
    letter_count_map[letter] = letter_count_map[letter]+1 if letter in letter_count_map.keys() else 1

Примечание: letter_count_map[letter]+1 if letter in letter_count_map.keys() else 1 — это В самом деле медленный/многословный способ написания letter_count_map.get(letter, 0) + 1.

ShadowRanger 30.05.2019 04:44

@ShadowRanger спасибо за ответ. Чтобы уточнить, вы говорите, что letter_count_map.get(letter, 0) + 1 более эффективен? Если да, то почему он более производительный?

Gopinath Taget 30.05.2019 04:59

@GopinathTaget: он позволяет избежать создания ненужного представления ключей (хотя вы можете удалить .keys() из исходного кода, чтобы получить тот же эффект), избегает проверки сдерживания с последующим поиском в пользу простого поиска и избегает инструкций ветвления байт-кода. Это может быть не намного быстрее (вызовы методов имеют раздражающе высокие фиксированные накладные расходы, хотя они были уменьшены в 3.7, если вы вызываете с чисто позиционными аргументами), но это много короче/четче.

ShadowRanger 30.05.2019 05:03

Вы также можете использовать defaultdict, чтобы упростить код.

from collections import defaultdict

def letter_count(input_str):
    letter_count_map = defaultdict(lambda: 0)

    for c in input_str:
        letter_count_map[c] += 1
    print(letter_count_map)

letter_count("serendipity")

Спасибо за фрагмент. Я это проверю.

Gopinath Taget 30.05.2019 07:51

К вашему сведению, defaultdict(int) достигнет той же цели. Не нужно lambda.

ShadowRanger 30.05.2019 12:37

Или даже короче: collections.Counter("serendipity") Все зависит от того, пишете ли вы код, чтобы учиться, или у вас есть реальная проблема, которую нужно решить.

Duncan 30.05.2019 13:24

Другие вопросы по теме