Продвинутый ввод-вывод

Ввод

Ввод списка слов из одной строки

Python позволяет считывать с помощью функции input() только всю строку целиком до следующего перевода строки.

Но что делать, если мы хотим считать несколько значений из одной строки? В этом нам поможет метод split(). Давайте напишем программу, которая считывает несколько слов из одной строки и выводит их в обратном порядке:


In [8]:
words = input().split()
words.reverse()

# Пока выводим по одному слову в строке. Скоро научимся выводить сразу много слов в одной строке.
for word in words:
    print(word)


one two three
three
two
one

То же самое более подробно:


In [10]:
# Считываем одну строку с клавиатуры. Она содержит все символы, включая пробелы.
line = input()
print('Строка: "' + line + '"')

# Разбиваем строку по пробельным символам и получаем список слов
words = line.split()
print('Список отдельных слов:', words)

# Переворачиваем список слов
words.reverse()
print('Перевёрнутый список слов:', words)

# Проходим по всем словам из списка и выводим каждое
for word in words:
    print(word)


one two three
Строка: "one two three"
Список отдельных слов: ['one', 'two', 'three']
Перевёрнутый список слов: ['three', 'two', 'one']
three
two
one

Частая ошибка — забыть скобки после input:


In [12]:
line = input.split()


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-12-c2a025ff0009> in <module>()
----> 1 line = input.split()

AttributeError: 'function' object has no attribute 'split'

Ошибка переводиться с английского как ОшибкаАтрибута: У объекта типа 'функция' нет атрибута 'split'.

Так происходит потому что:

  • input — это объект-функция (тип function)
  • input() — это вызов функции, который возращает строку (тип str)
  • У объектов типа str (строк) определён метод split, а у объектов типа function (функций) — нет
  • Мы попытались вызвать метод split у объекта типа function

Похожая проблема произойдёт если забыть скобки после split.

Ввод списка чисел из одной строки

Чтобы считать одно число из строки, нам приходилось преобразовывать результат функции input() к целому числу (int(input())), потому что input() возращает строку (str).

input().split() возращает список строк. Если мы хотим получить список чисел, то нам надо преобразовать каждую из этих строк в число. Самый прямолинейный способ это сделать — используя цикл:


In [19]:
words = input().split()

# Преобразуем строки в числа
numbers = []
for word in words:
    numbers.append(int(word))

print("Числа:", numbers)


2018 42 3
Числа: [2018, 42, 3]

Обратите внимание на отсутствие кавычек вокруг элементов списка. Это значит, что у нас там числа, а не строки.

Но Python позволяет сделать то же самое короче и эффективнее, использовав немного чёрной магии:


In [20]:
# Такое считывание работает быстрее, чем предыдущий пример
numbers = list(map(int, input().split()))
print("Числа:", numbers)


2018 42 3
Числа: [2018, 42, 3]

Функция map(func, lst) возращает «список», полученный применением функции func к каждому элементу списка lst.

Мы взяли «список» в кавычки, потому что это не совсем список, а объект типа map, который иногда ведёт себя также как список, а иногда — нет. Поэтому мы явно преобразуем результат в полноценный список (list).

Ввод двух чисел из одной строки

Для этого надо считать список чисел и сделать параллельное присваивание:


In [18]:
# Обратите внимание на отсутствие преобразования в список. Здесь в нём нет необходимости.
a, b = map(int, input().split())
print(a, type(a))
print(b, type(b))


3 5
3 <class 'int'>
5 <class 'int'>

Аналогично можно ввести три числа:


In [22]:
# Обратите внимание на отсутствие преобразования в список. Здесь в нём нет необходимости.
a, b, c = map(int, input().split())
print(a, type(a))
print(b, type(b))
print(c, type(c))


5 8 13
5 <class 'int'>
8 <class 'int'>
13 <class 'int'>

Или две строки:


In [23]:
first_name, last_name = input().split()
print(first_name, type(first_name))
print(last_name, type(last_name))


Дональд Кнут
Дональд <class 'str'>
Кнут <class 'str'>

Вывод

Аргументы функции print

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

  • sep — что выводить между значениями. По умолчанию " " (пробел). От английского separator — разделитель.
  • end — что выводить после последнего значениями. По умолчанию "\n" (перевод строки).

Задаются они в конце после всех аргументов:


In [26]:
day, month, year = '5', '07', '2018'
# День месяц и год выводятся через точку, а не через пробел
print(day, month, year, sep='.')


5.07.2018

In [30]:
# В конце вывелись три восклецательных знака. Между "Sparta" и "!!!" нет пробела.
print("This", "is", "Sparta", end="!!!")


This is Sparta!!!

In [32]:
# Выводим список чисел в одну строку
for x in [1, 1, 2, 3, 5, 8, 13, 21]:
    # Заменяем end на пробел, чтобы продолжать выводить в той же строке
    print(x, end=" ")
# Выводим первод строки в конце
print()


1 1 2 3 5 8 13 21 

Вывод многих значений в одной строке

Выше показан способ это сделать, но он слишком многословен. Того же самого можно добиться так:


In [34]:
numbers = [1, 1, 2, 3, 5, 8, 13, 21]
print(*numbers)


1 1 2 3 5 8 13 21

print(*lst) — это то же самое, что и передать все элементы списка функции: print(lst[0], lst[1], ..., lst[len(lst) - 1]).

Форматированный вывод

Для более сложного вывода можно воспользоваться методом format. Он позволяет подставить значения в произвольную строку.


In [37]:
a, b = 8, 13
# Значения подставляются вместо фигурных скобок:
print('{} + {} = {}'.format(a, b, a + b))


8 + 13 = 21

In [49]:
# Получаем доступ к переменной pi из
from math import pi

# По умолчанию для дробных чисел выводиться некоторое фиксированное количество знаков после точки
print(pi)

# Так можно точно указать точность
print('{:.5}'.format(pi))
print('{:.30}'.format(pi))


3.141592653589793
3.1416
3.14159265358979311599796346854

Более подробно про форматированный вывод можно почитать тут: TODO