Наибольшее нечетное число
Попросите пользователя ввести 10 целых чисел, а затем вывести наибольшее нечетное число, которое было введено. Если не было введено нечетное число, распечатайте сообщение об этом.
Я пытался решить эту проблему с помощью python, и я думаю, что нашел способ, который охватывает все возможные случаи, учитывая математическое определение нечетного числа. Чтобы быть уверенным, я хотел бы проверить, верен ли мой код с учетом ваших собственных критериев.
counter = 0
odd = []
while counter < 10:
x = int(input("Enter a number: "))
if abs(x)%2 != 0:
odd.append(x)
counter += 1
if len(odd) == 0:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odd))
Ответы
Для вашей текущей программы мы можем улучшить пару вещей:
- Переименовать
odd
вodds
(так как это аlist
). - Используйте
not odds
вместоlen(odds) == 0
(см. Как проверить, пуст ли список? Почему это предпочтительнее). - Удалить
counter
. Поскольку мы используем толькоcounter
вwhile
условии, мы можем фактически заменить целоеwhile
наfor _ in range(10)
. - Следуйте PEP 8 . Например, используя 4 пробела для каждого уровня отступа.
С учетом всех этих изменений мы получаем:
odds = []
for _ in range(10):
x = int(input("Enter a number: "))
if abs(x) % 2 != 0:
odds.append(x)
if not odds:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odds))
Но мы также можем повысить эффективность этой программы. Прямо сейчас мы отслеживаем все нечетные числа, прежде чем выбрать максимальное. Это означает, что сложность пространства O (N). Мы можем изменить это значение на O (1), отслеживая наибольшее нечетное число следующим образом:
max_odd = None
for _ in range(10):
x = int(input("Enter a number: "))
if abs(x) % 2 != 0:
max_odd = x if max_odd is None else max(max_odd, x)
if max_odd is None:
print("No odd number was entered")
else:
print("The largest odd number is: ", max_odd)
Обратите внимание, что мы используем None
для обозначения того, что до сих пор не было введено нечетное число, и в этом случае при вводе нечетного числа мы устанавливаем max_odd
его x
напрямую. В противном случае, мы устанавливаем max_odd
в max(max_odd, x)
.
Для этого типа программ вы не заметите повышения эффективности за счет уменьшения занимаемой площади. Но научившись распознавать, где это сокращение возможно, вы сможете увидеть те же закономерности в программах, где это действительно важно.
Наконец-то есть еще одна вещь, которую вы можете сделать. Если вы хотите, чтобы программа продолжала накапливать числа в случае, если str
случайно набран a , который не может быть проанализирован как число (например, ""
), мы можем использовать try
/, except
обернутый while
следующим образом:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Это заменит:
x = int(input("Enter a number: "))
в исходном коде. Это будет продолжать предлагать пользователю ввести, str
который можно проанализировать как, int
пока они не сделают это. Поскольку все это происходит на той же итерации for
, количество чисел, которые они набирают (в нашем случае 10), не будет уменьшено.
Дополнение к предыдущему обзору:
- Когда
x
является целым числом,abs(x) % 2
эквивалентноx % 2
Python. Выходные данные оператора по модулю%
имеют тот же знак, что и второй операнд. - При запуске кода вне метода / класса рекомендуется помещать код внутри основной защиты . См. Здесь для получения дополнительных объяснений.
В Python 3.8 код можно сократить, используя оператор присваивания :=
вместе с max
функцией.
if __name__ == "__main__":
# Number generator
num_gen = (o for _ in range(10) if (o := int(input("Enter a number: "))) % 2 != 0)
max_odd = max(num_gen, default=None)
if max_odd is None:
print("No odd number was entered")
else:
print(f"The largest odd number is: {max_odd}")
Обертывание int(input("Enter a number: "))
функции обеспечивает лучшую читаемость:
def read_input() -> int:
return int(input("Enter a number: "))
if __name__ == "__main__":
num_gen = (o for _ in range(10) if (o := read_input()) % 2 != 0)
max_odd = max(num_gen, default=None)
if max_odd is None:
print("No odd number was entered")
else:
print(f"The largest odd number is: {max_odd}")
Другой вариант, который обрабатывает недопустимые вводимые пользователем данные, выглядит следующим образом:
def read_input() -> int:
while True:
try:
return int(input("Enter a number: "))
except ValueError:
continue
if __name__ == "__main__":
try:
max_odd = max(o for _ in range(10) if (o := read_input()) % 2 != 0)
print(f"The largest odd number is: {max_odd}")
except ValueError:
# Since read_input() no longer raises ValueError, the except
# statement here only handles the cases where max() gets no inputs
print("No odd number was entered")
Могу я спросить, какой язык программирования вы практиковали до Python?
Я хочу упомянуть об этом однострочник:
max(l,key=lambda x:(x%2,x))
предполагая, что вы уже как- l
то ввели, например
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
Как работает код? Он ищет максимум key(x)
за x
в l
и возвращает такое x
. Ключевым моментом здесь является лямбда-функция, которая возвращает кортеж (1,x)
для нечетного x
и (0,x)
четного x
. Кортежи сравниваются слева направо, например, (1,x)>(0,y)
для каждого x
и y
. Итак, мы просто говорим: «Дайте мне максимум l
, предполагая, что нечетное число всегда больше четного».
Так вся программа будет выглядеть так
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
m=max(l,key=lambda x:(x%2,x))
if m%2:
print('The largest odd number is: %d'%m)
else: #the greatest is even, therefore no odd numbers
print('No odd number was entered')
Коротко, красиво и легко, как питон.
Но я согласен с тем, что блок try-except вокруг int(input())
принятого ответа полезен, а также без предварительного сохранения всего списка нечетных значений.
Я только хотел продемонстрировать парадигму функционального программирования на python, когда вы просто говорите python: «Я хочу, чтобы это было сделано (например, максимальное значение)», и он делает это за вас, вам не нужно объяснять, как он должен это делать.
Спасибо за прочтение.
Я постараюсь опираться на последнее предложение принятого ответа.
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Я определенно поддерживаю это предложение, оно позволяет вашей программе корректно обрабатывать неверный ввод, а не просто давать сбой.
Однако это создает проблему удобства использования. Пользователь, который просто ввел букву в число, вероятно, этого не заметил. Они будут думать, что ввели намеченный номер, переходят к следующему, а затем запутаются в конце, когда они думают, что они ввели все числа, но компьютер все еще запрашивает следующий.
Лучше дать им обратную связь:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
print("Invalid number will be ignored.")
continue
... или, что еще лучше, напечатайте их набранный номер обратно на них:
while True:
try:
inputString = input("Enter a number: ")
x = int(inputString)
break
except ValueError:
print("Invalid number will be ignored: {}".format(inputString))
continue
Я бы также подумал о том, чтобы сохранить полный список введенных допустимых чисел, а не только нечетных, и распечатать их все обратно пользователю до получения результата, чтобы дать ему последний шанс обнаружить опечатки. В конце концов, они могли ошибиться в правильном, но непредусмотренном номере. Обратите внимание, что это увеличит использование памяти, и некоторые сочтут это чрезмерным обменом данными.
print("Numbers provided are: {}".format(all_valid_numbers_inputted))
if not odds:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odds))
Если вы сделаете это, следующим шагом будет избавление от переменной "шансы" и определение наибольшего коэффициента прямо из полного списка.
Ключевой момент здесь: на каждом этапе процесса выполняется только одна простая вещь. Таким образом вы строите программы - по одному постепенному, строго определенному шагу за раз. Не смешивайте все в беспорядке - например, цикл, в котором мы взаимодействуем с пользователем, а также выполняем преобразования и вычисления, которые потребуются позже.
def as_int(s):
try:
return int(s)
except Exception:
return 0
N = 3
MSG = 'Enter number: '
replies = [input(MSG) for _ in range(N)] # Interact.
nums = [as_int(r) for r in replies] # Convert.
odds = [n for n in nums if n % 2] # Compute.
if odds: # Report.
print(max(odds))