Я пытаюсь напечатать значение ключа при вводе строки с плавающей запятой.
Вот мой код:
number_dict = {1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven', 8: 'Eight', 9: 'Nine', 0: 'Zero', '-': 'Negative', '.': 'Point'}
number = input('Enter a number: ')
print(f'As Text:', end = ' ')
for char in number:
for key, value in number_dict.items():
if char == key:
print(value, end = ' ')
elif int(char) == key:
print(value, end = ' ')
Что я делаю не так? Почему значения, связанные с '.', не связаны? и печать клавиш «-»? Доступ к ним следует осуществлять в состоянии elif.
Уже существует блок try
и except
для учета ValueError. Я просто не хотел публиковать код целиком, но я знаю об ошибке и уже учел ее.
Заранее спасибо за помощь!!
Целочисленные ключи печатаются нормально. Я попытался изменить порядок моего оператора if, который, как я думаю, не приведет к недопустимому литералу для int(), и код выполнился точно таким же непреднамеренным образом.
if elif char == key: print(value, end = ' ') elif int(char) == key: print(value, end = ' ') Дает те же результаты и не должен вызывать целочисленную ошибку, если заказал вот так.
Если на вопрос «Почему [sic] значения, связанные с '.' и печать клавиш «-»? вы имели в виду, что было выброшено исключение, вам следует отредактировать эту важную информацию в вопросе. Однако обычный способ использования dict — for char in number: print(number_dict[char], end=' ')
. (Чтобы это работало, вам нужно изменить целочисленные ключи на строки, например, с 1
на '1'
. Это не единственное решение, но хорошо иметь однородные типы ключей (все строки) вместо некоторых целых чисел и некоторых строк. .)
Зачем вообще перебирать словарь? это не то, как вы получаете значения от dict
?
Нет, я не имел в виду, что было выброшено исключение. Я не включил свое исключение в опубликованный код, поскольку оно уже работало правильно и учитывалось. Весь этот код помещен в блок try
с Except
, но я не об этом спрашивал.
Я могу перебирать словарный список кортежей или перебирать список, содержащий значения, используя .values(). Происходят те же непредвиденные результаты. У вас есть лучший способ?
@Carissa, они подчеркивают, что словари следует использовать для прямого получения значений, например my_dict[key]
или my_dict.get(key)
, перебор их как бы сводит на нет суть. Действительно, если бы вы это сделали, вы бы избежали этой проблемы.
Я ценю ваш ответ, но вот в чем дело. значение = номер_дикт[ключ]. Я написал код именно таким образом, но все равно получаю ту же ошибку. Если вы запустите код, как вы предложили, вы тоже получите ту же ошибку. Однако я ценю ваши отзывы!
@Карисса, нет. Вы получаете другую ошибку. Пожалуйста, всегда предоставляйте минимально воспроизводимый пример. Здесь есть несколько вещей, которые идут не так по-разному, и вы продолжаете изменять аспекты имеющегося у вас кода, а также фактически не демонстрируете реальный код, который вы используете. Пожалуйста, не делай этого.
Итак, просто подумайте о том, что происходит. Вы повторяете диктовку. итак, на первой итерации key == 1
. Итак, когда char == '.'
., то key == char
ложно. Затем вы попадаете в int('.')
, отсюда и ошибка (или, на самом деле, в вашем собственном коде, который вы не хотите нам показывать, исключение перехватывается, и оно молча терпит неудачу)
Я только пытаюсь понять... если изменить значение на number_dict[key], результат не изменится. Я запустил свой код, как вы предложили, и получил те же результаты, поэтому я определенно не понимаю, что вы имеете в виду. Я просто хочу решить проблему.
Чтобы мы действительно могли вам помочь, вы должны предоставить минимально воспроизводимый пример. Для эффективного взаимодействия мы должны говорить об одном и том же коде, даже если это всего лишь уменьшенный игрушечный пример. Это часть правил сайта. Но вы можете попробовать что-то вроде if char.isdigit(): prin(number_dict[int(char)])
с else: print(number_dict[char])
или другой подход — сначала использовать в словаре только строки. Обычно вы хотите избежать смешивания типов в контейнерах.
Извините, что не показывал свой полный код! ржу не могу. Ничего личного, для меня самое легкое было исключение. Это единственная часть, от которой я хотел помощи. Я знаю, что это усложняет понимание, поэтому я понимаю и благодарен за помощь.
Хорошо, это нормально, но, пожалуйста, поймите, что мы не просим «полный код», мы просим минимально воспроизводимый пример. Это не то же самое. Если вам нужна помощь в отладке, вам нужно приложить немного усилий, чтобы помочь нам помочь вам. Частично мы стараемся изо всех сил создать пример, который мы могли бы запустить самостоятельно, не догадываясь, что вы делаете. удаление ненужных частей вашего общего кода — это хорошо! Но нам все равно придется говорить об одном и том же коде.
Я отредактировал его и проголосовал за повторное открытие, но я думаю, что проблема по-прежнему заключается в том, что я сказал вам в своем комментарии выше, я повторю это здесь: «Вы выполняете итерацию по диктовке. Итак, на первой итерации key == 1. Итак, когда char == '.'., тогда key == char имеет значение false. Тогда вы попадаете в int('.'), отсюда и ошибка ". За исключением того, что теперь эта ошибка обнаруживается в вашем предложении исключения, но ни одно из условий в этом случае не является истинным, поскольку number
- это что-то вроде '3.4'
, что не запускает ваши условия if
или elif
в предложении except
.
И, пожалуйста, не говорите нам, что в вашем реальном коде нет отступов. Я предполагаю, что ваш код не вызывает SyntaxError, пожалуйста, в будущем просто исправьте это, чтобы в коде, который вы указываете в вопросе, не было ошибок.
@juanpa.arrivillaga Нет. Ошибка отступа была очевидна. Как я уже сказал, это произошло только тогда, когда я скопировал сюда код и попытался отформатировать. Я обновил значение до number_dict[key], как вы сказали и как я уже пробовал, и оно по-прежнему отображает непреднамеренный вывод, который я пытаюсь исправить.
Для справки: я не перебираю словарь. number_dict.items()
создает список кортежей = [(ключ, значение)] для каждой пары ключ:значение в словаре, над которым выполняется метод.
Вот что такое перебор словаря. Кстати, поддерживаю решение в моем исходном комментарии (обратите внимание на часть об изменении ключей словаря на строки, что необходимо для его работы). Вам следует избегать try
, потому что это превращает все различные проблемы в одно и то же поведение.
@juanpa.arrivillaga Я говорю об этом искренне. Спасибо за вашу помощь и за то, что помогли мне снова открыть вопрос. :) Я знаю, что мне, как новичку, было непросто. Надеюсь, вы знаете, что ваш отзыв был принят к сведению и оценен по достоинству. Я помню, что .items() технически возвращает элемент словаря. Так что извините за то, что я туда-сюда. Я просто был расстроен, и я знаю, что это не облегчило вам объяснение. Думаю, я просто слишком долго смотрел на код, и мне нужен был перерыв, чтобы мыслить яснее. Надеюсь, вы поверите, что я имею в виду именно это.
Этот цикл никогда не будет выполняться более одного раза, поскольку он заканчивается знаком break
:
for key, value in number_dict.items():
if char == key:
print(number_dict[key], end = ' ')
elif int(char) == key:
print(number_dict[key], end = ' ')
break
break
не имеет никакого смысла. Как только вы это удалите, вы столкнетесь с основной проблемой: если int(char)
выдает исключение (как это происходит, когда вы передаете ему символы "-"
или "."
), вы перехватываете исключение вне цикла. Это также означает, что цикл не выполняется для остальных элементов словаря.
Чтобы лучше понять, что происходит, с помощью отладчика пройдите цикл с помощью char = "-"
.
Теперь вы можете это исправить, перехватив исключение внутри цикла:
for key, value in number_dict.items():
if char == key:
print(number_dict[key], end = ' ')
else:
try:
if int(char) == key:
print(number_dict[key], end = ' ')
except ValueError:
pass # do nothing
Но все это не то, как вам следует пользоваться словарем. Словари предназначены для поиска информации непосредственно по ключу; перебирая его для проверки каждого ключа, вы теряете смысл. Чтобы очистить ваш код, я бы рекомендовал начать с того, чтобы сделать ваши ключи dict однородными, то есть все строки вместо смеси строк и целых чисел:
number_dict = {'1': 'One', '2': 'Two', '3': 'Three', '4': 'Four', '5': 'Five', '6': 'Six', '7': 'Seven', '8': 'Eight', '9': 'Nine', '0': 'Zero', '-': 'Negative', '.': 'Point'}
Теперь вы можете получить значение, соответствующее любому символу, независимо от того, является ли это цифрой, с помощью number_dict[char]
.
Также хорошей практикой является избегать создания и перехвата исключений, когда это возможно, а когда это необходимо, делать покрытие try
как можно меньшим — в противном случае вы рискуете поймать то, чего не ожидали, и неправильно с ним справиться.
while True:
number = input('Enter a number: ')
# can check this ahead of time! helps limit the `try` responsibilities
if ',' in number:
print('Please try again without entering commas.')
continue
# much smaller `try`!
try:
float(number)
except ValueError:
print(f'"{number}" is not a valid number. Please try again.')
continue
print(f'As Text:', end = ' ')
for char in number:
print(number_dict[char], end = ' ')
Наконец, обратите внимание, что float
принимает некоторые вещи, которые вы не учли, например константы "-inf"
/"inf"
/"nan"
, экспоненциальное обозначение "1e-1"
и пробелы. Вам следует использовать более строгую проверку, что также означает, что try
вообще не нужен (хорошо!). Вот пример того, как это сделать с помощью регулярных выражений:
import re
number_dict = {'1': 'One', '2': 'Two', '3': 'Three', '4': 'Four', '5': 'Five', '6': 'Six', '7': 'Seven', '8': 'Eight', '9': 'Nine', '0': 'Zero', '-': 'Negative', '.': 'Point'}
while True:
number = input("Enter a number: ")
if "," in number:
print("Please try again without entering commas.")
continue
if not re.fullmatch(r"-?(?!\.?\Z)[0-9]*(?:\.[0-9]*)?", number):
print(f"{number!r} is not a valid number. Please try again.")
continue
text = " ".join(number_dict[char] for char in number)
print(f"As Text: {text}")
но поскольку вы, вероятно, еще не знаете регулярные выражения, попробуйте в качестве упражнения написать функцию строгой проверки с циклом и методом str.isdigit
, который вы уже использовали. Подумайте о том, должен ли "1."
печатать «Одна точка» или «Один», или это ошибка!
Печатают, печатают
invalid literal for int() with base 10: '.'
. Чего вы ожидали, если вы попытаетесь преобразовать их вint
?