Один из похожих кодов не работает. В чем разница?

Рейтинг: 0Ответов: 2Опубликовано: 25.04.2023

Из строки произвольной длинны нужно вывести все числа.

Этот код работает:

print(*(i for i in input() if i.isdigit()), sep="")

Этот код не работает:

print(i for i in input() if i.isdigit())

и выдает

<generator object <genexpr> at 0x7ff106c5b350>

Подскажите, пожалуйста, в чем разница между ними, помимо выведения элементов через пробел и разделителя.

Ответы

▲ 1

Звёздочка перед генератором распаковывает значения в генераторе. Без неё вы получаете просто генератор, с которым можно в дальнейшем работать через periodicals или циклами.

arr = ['яблоко', '1', 'мандарин', '12', 'апельсин']

print(*(i for i in arr if i.isdigit()), sep="") ###112

print([i for i in arr if i.isdigit()]) ###['1', '12]

generator = (i for i in arr if i.isdigit())
print(next(generator))
#1

Иначе говоря, генераторы — это специальная конструкция, можно вместо них использовать скобки, тогда получится список и дополнительных махинаций в виде звёздочки или next() они не требуют.

Генераторы же полезны когда в функцию необходимо передать несколько параметров, можно указать их в списке и передать через звёздочку не расписывая каждый. print как раз та самая функция, которая может принимать неограниченное число параметров на вход.

▲ 1

Второй код прекрасно работает. В нём вы передаёте на вход методу print генератор и он вам печатает информацию о том, что на вход получен генератор. Питон всегда так делает с объектами, которые он не очень понимает, как ему нужно выводить. Если вы хотите получить значения, генерируемые этим генератором, то вам нужно тем или иным образом проитерироваться по этому генератору. Например, как это сделано в первом коде - распаковать значения из генератора с помощью оператора *. Или, например, вот так, с помощью метода str.join:

print(''.join(i for i in input() if i.isdigit()))