С' 2015

1. Hello world!

Как правило, первая программа которую пишут на языке - это "Hello world!". Ниже приведен полный код этой программы на языке Python 3.

In [1]:
print("Hello world!")
Hello world!

Здесь, мы первый раз сталкиваемся с функцией print, это функция вывода. В простейшем случае, чтобы написать что-нибудь на экран нам достаточно написать print() и внутри скобочек, то что мы хотим вывести.

In [2]:
print(10)
print(2 + 2)
print(11, 11)
print("Hi!", 42, 12.5)
10
4
11 11
Hi! 42 12.5

2.Переменные

Конечно, как в любом языке программирования, в Python есть переменные. Самое первое, что мы научимся делать -- это присваивать переменной значение. Ниже показано, как это сделать.

In [3]:
a = 5
b = 7 + 3
print("a + b =", a + b)
a + b = 15
In [4]:
c = a + b
print('c =', c) #строки так же можно задавать в одинарный кавычках, "abc" и 'abc' это одно и то же 
c = 15

В этом куске кода выше есть как минимум одна новая вещь: комментарий, он начинается с символа # и продолжается до конца строки.

In [5]:
some_string = "string variable"
print("some_string =", some_string)
some_string = string variable

Как вы заметили, в отличие от С/С++, Pascal мы при объявлении переменной не задавали ее тип. Все очень просто в Python у переменной нет типа, подобное свойство языка называют динамической типизацией.

Пример ниже демонстрирует это свойство чуть-чуть подробнее.

In [6]:
a = 5
print(a)
a = "A is string now!"
print(a)
5
A is string now!

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

3.Арифметические операции

Давайте научимся складывать, умножать, вычитать и производить другие операции с целыми или вещественными числами. Стоит понимать, что целое число и вещественное число это совсем разные вещи для компьютера.

Список основных арифметических действий, которые вам понадобятся:

  • Сложение: +
  • Вычитание: -
  • Умножение: *
  • Вещественное деление: /
  • Целочисленное деление (округление производится вниз): //
  • Взятие остатка (работает с действительными числами тоже): %
  • Возведение в степень: **
In [7]:
a = 1
b = 2
print(a + b)
3
In [8]:
a = 2.0
b = 1
print(a + b)
3.0
In [9]:
a = 4
b = 5
print(a - b)
-1
In [10]:
a = 3.0
b = 4
print(a - b)
-1.0
In [11]:
a = 2
b = 4
print(a * b)
8
In [12]:
a = 2.1
b = 4
print(a * b)
8.4
In [13]:
a = -2.1
b = 4
print(a * b)
-8.4
In [14]:
a = 10
b = 2
print(a // b)
5
In [15]:
a = 10
b = 3
print(a // b)
3
In [16]:
a = -10
b = 3
print(a // b)
-4
In [17]:
a = 10
b = 3
print(a / b)
3.3333333333333335
In [18]:
a = 10
b = 2
print(a / b)
5.0
In [19]:
a = 10
b = 2
print(a % b)
0
In [20]:
a = 10
b = 3
print(a % b)
1
In [21]:
a = 10
b = 3.5
print(a % b)
3.0
In [22]:
a = -10
b = 3
print(a % b)
2
In [23]:
a = 2
b = 2
print(a ** b)
4
In [24]:
a = -2
b = 2
print(a ** b)
4
In [25]:
a = 2
b = -2
print(a ** b)
0.25
In [26]:
a = 2.5
b = 2
print(a ** b)
6.25
In [27]:
a = 4
b = 0.5
print(a ** b)
2.0
In [28]:
a = 4
b = 0.5
print(a ** b)
2.0
In [29]:
a = -4
b = 0.5
print(a ** b)
(1.2246467991473532e-16+2j)
In [30]:
a = -4.2
b = -0.5
print(a ** b)
(2.9878322515602243e-17-0.4879500364742666j)

Так же существует специальный операторы позволяющие сократить записи вида: a = a + 5. Все эти операторы записываются как "оператор=", ниже несколько примеров.

In [31]:
a = 1
a += 2 #эквивалент а = а + 2
print(a)
3
In [32]:
a = 3
b = 2
a *= b #эквивалент а = а * b
print(a)
6
In [33]:
a = 3
b = 2
a **= b #эквивалент а = а ** b
print(a)
9

4.Операторы if..elif..else

Думаю, всем понятно, как работает оператор if, ниже несколько примеров, чтобы разобраться с синтаксисом python.

In [34]:
if 5 < 3:
    print("Правда")
else:
    print("Ложь")
Ложь
In [35]:
if 9 * 7**2 > 8 * 5**2:
    print("Правда")
else:
    print("Ложь")
Правда
In [36]:
if True:
    print("Ветка if")
else:
    print("Ветка else")
Ветка if
In [37]:
if False:
    print("Ветка if")
else:
    print("Ветка else")
  
Ветка else
In [38]:
if False:
    print("Ветка if")
elif True:
    print("Ветка elif")
else:
    print("Ветка else")
    
Ветка elif

Понятно, что после if может стоять не только значение True или False. Посмотрим, что делает Python, если после if стоит нечто более странное?

In [39]:
if 0:
    print("Ветка if")
else:
    print("Ветка else")
Ветка else
In [40]:
if 5:
    print("Ветка if")
else:
    print("Ветка else")
Ветка if
In [41]:
if -1:
    print("Ветка if")
else:
    print("Ветка else")
Ветка if
In [42]:
if "":
    print("Ветка if")
else:
    print("Ветка else")
Ветка else
In [43]:
if "abc":
    print("Ветка if")
else:
    print("Ветка else")
Ветка if
In [44]:
if []:
    print("Ветка if")
else:
    print("Ветка else")
Ветка else
In [45]:
if [2, 3, 4]:
    print("Ветка if")
else:
    print("Ветка else")
Ветка if

Посмотрим, как устроены логические операции и операции сравнения в Python.

Вот список тех из них, которыми вы будете пользоваться наиболее часто:

  • Равенство: ==
  • Неравенство: !=
  • Меньше: <
  • Меньше либо равно: <=
  • Больше: >
  • Больше либо равно: >=
  • Логическое или: or
  • Логическое и: and
  • Логическое отрицание: not

Рассмотрим несколько примеров.

In [46]:
print(5 > 2)
True
In [47]:
print(not 5 > 2)
False
In [48]:
a = 5
b = 2
print(a > b and a >= b)
True
In [49]:
a = 5
b = 2
print(True and a > 2)
True
In [50]:
a = 5
b = 2
print(False or b >= 2)
True
In [51]:
a = 5
b = 2
print(b == a)
False
In [52]:
a = 5
b = 2
print(b != a)
True

Напоследок несколько специфичных вариантов.

In [53]:
print("abc" and [1, 2, 34])
[1, 2, 34]
In [54]:
print("abc" < [1, 2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-54-4be796a5ac22> in <module>()
----> 1 print("abc" < [1, 2])

TypeError: unorderable types: str() < list()
In [55]:
print("abc" == [1, 2])
False
In [56]:
print("abc" != [1, 2])
True

Конечно, в условии после if чаще всего и приходится использовать логические операции. В качестве примера, давайте напишем программу, проверяющую является ли данный год високосным.

In [57]:
year = 2015

if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
    print("YES")
else:
    print("NO")
NO

Единственная проблема у кода выше - это невозможность считать год с клавиатуры, как можно заметить, мы задали его в явном виде. Для решения этой проблемы нам понадобится функция input, она считывает строчку (до перевода строки) из stdin (стандартного потока ввода, который обычно связан с клавиатурой). Также нам понадобится функция int, она преобразует число записанное в виде строки в число.

In [58]:
year = int(input())

if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
    print("YES")
else:
    print("NO")
2015
NO

5.Цикл while

Самый просто устроенный цикл - while. Он работает точно так же как и в остальных языках программирования.

In [59]:
i = 0
while i < 5:
    i += 1
    print(i)
1
2
3
4
5

Естественно, после while может стоять любое условие.

Также есть оператор break, он заканчивает выполнение цикла.

In [60]:
i = 0
while True:
    print("before", i)
    if i == 2:
        break
    print("after", i)
    
    i += 1
before 0
after 0
before 1
after 1
before 2

Для примера давайте напишем программу, которая выводит наименьшую степень двойки, которая больше заданного числа $n$.

In [61]:
n = int(input())

cp, i = 1, 0
while n >= cp:
    cp *= 2
    i += 1
    
print("cp = %d, i = %d" % (cp, i)) #это более удобный способ форматирования строк, ниже несколько комментариев про него
14
cp = 16, i = 4

В задаче выше мы воспользовались несколькими новыми вещами.

Во-первых, конструкция вида a, b = c, d , называются параллельным присваиванием. В этом случае переменной a будет присвоено значение c, а переменной b значение d. В некоторых ситуациях это бывает очень удобно.

Во-вторых, если нам нужно получить строку, содержащую несколько целых чисел с некоторым форматированием, то это можно сделать с помощью конструкции подобной конструкции выше. Формальное объяснение этой конструкции достаточно громоздко, давайте посмотрим на несколько примеров.

In [62]:
print("I'am %d years old." % 19)
I'am 19 years old.
In [63]:
print("2 * 2 = %d" % (2 * 2)) #самый простой пример просто вставляющий целое число в нужное место
2 * 2 = 4
In [64]:
print("%02d:%02d" % (15, 2)) # немного форматирования самого числа
15:02

6. List и tuple

Несколько общих слов. List это некоторое подобие массива в "привычных" вам языках программирования лишь с тем отличием, что в list могут храниться элементы разных типов. Давайте попробуем разобраться на примерах.

In [65]:
a = [1, 2, "Hi"] #мы создали список и присвоили переменной а этот список
print(a[0], a[1], a[2]) #так обращаться к элементам списка, элементы индексируются с нуля

b = list() #таким образом можно создать пустой список
1 2 Hi

В Python есть отрицательная индексация. $-1$ элемент это последний элемент, $-2$ элемент это предпоследний элемент списка и так далее. После примеров ниже должно стать совсем понятно.

In [66]:
a = [1, 2, "Hi"] 
print(a[-2]) 
2
In [67]:
b = ["a", 1, 2, 3, 4, "b", -10, [1, 2, 3], 3.4, "!!!"] #элементом списка может быть список
print(b[-3])
[1, 2, 3]
In [68]:
a = [1, 2, "Hi"] 
a[1] = 4 #можно изменить отдельный элемент
print(a) #можно вывести весь список, но он это делается в неудобном формате
[1, 4, 'Hi']

Бывает такое, что нам нужна только некоторая часть списка, например все элементы с $5$ по $10$, или все элементы с четными индексами. Подобное можно сделать с помощью срезов.

Срез задается одним из нескольких способов:

  • список[первый элемент:следующий после последнего элемента]
  • список[первый элемент:] в этом случае последний это последний элемент списка
  • список[:следующий после последнего элемента] в этом случае нулевой элемент это первый элемент списка
  • список[первый элемент:следующий после последнего элемента:шаг] шаг - промежуток между соседними элементами, которые нужно взять, по умолчанию шаг равен 1

Нужно понимать, что любой из параметров может быть опущен так, например, срез a[::] будет содержать просто весь список a.

In [69]:
print([1, 2, 3, 4, 5, 6, 7, 8][:5])
[1, 2, 3, 4, 5]
In [70]:
print([1, 2, 3, 4, 5, 6, 7, 8][1:7:2])
[2, 4, 6]
In [71]:
print([1, 2, 3, 4, 5, 6, 7, 8][:0])
[]
In [72]:
print([1, 2, 3, 4, 5, 6, 7, 8][::2])
[1, 3, 5, 7]
In [73]:
print([1, 2, 3, 4, 5, 6, 7, 8][::-1])
[8, 7, 6, 5, 4, 3, 2, 1]
In [74]:
print([1, 2, 3, 4, 5, 6, 7, 8][2::-1])
[3, 2, 1]

Давайте немного подробнее поговорим о присваивании списков, с этим в Python есть несколько сложностей.

Как уже было сказано ранее, Python интерпретируемый язык. Во время выполнения, все данные которые у вас есть в программе он должен хранить, поэтому у интерпритатора во время выполнения хранится множество существующих объектов, и переменная это всего лишь ссылка на объект, который хранит интепритатор.

Давайте чуть-чуть подробнее изучим, как устроен лист с учетом ссылочного устройства.

In [75]:
a = [1, 2, 3, 4] #а - ссылка на лист, каждый элемент листа это ссылка на элементы 1, 2, 3, 4
b = a #b - ссылка теперь на тот же лист

print("id(a) = %d, id(b) = %d" % (id(a), id(b))) #в Python у каждого объекта есть свой id, это неокторое уничкальное число сопоставленное объекту

a[0] = -1
print("b =", b)
id(a) = 4533305928, id(b) = 4533305928
b = [-1, 2, 3, 4]

Также для списка есть набор удобных функций уже встроенных в Python, которые иногда упрощают жизнь. Давайте посмотрим на некоторые из них.

In [76]:
l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
print(min(l))
-2
In [77]:
#не стоит думать, что min можно брать только от list или tuple, конечно, существует min от двух элементов
print(min(12, 10))
10
In [78]:
print(sum([2, 3, 11, 1])) #эта функция суммирует все числа в list или tuple
17
In [79]:
l = [1, 2, 3]
l.append(4) #метод append добавляет элемент в конец списка
print(l)
l.pop() #метод pop удаляет из списка последний элемент
print(l)
[1, 2, 3, 4]
[1, 2, 3]
In [80]:
l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
print(l.index(3)) #заметьте, что в списке l у нас две тройки и index возвращает индекс первой из них
3
In [81]:
l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
print(l.index(115)) #если элемента нет в списке, то произойдет ошибка выполнения
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-81-573d67cff94a> in <module>()
      1 l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
----> 2 print(l.index(115)) #если элемента нет в списке, то произойдет ошибка выполнения

ValueError: 115 is not in list

Так же есть удобный метод sort, она сортирует список по невозрастанию.

In [82]:
a = [3, 2, 4, 1, 2]
a.sort()
print(a)
[1, 2, 2, 3, 4]

Еще одна приятная функция это reverse, она, как следует из названия, переворачивает список.

In [83]:
a = [1, 4, 2, 5, 2]
a.reverse()
print(a)
[2, 5, 2, 4, 1]

Tuple почти ничем не отличает от list, только он неизменяемый. То есть нельзя взять и изменить один элемент. Во всем остальном они буду идентичны.

In [84]:
a = (1, 2, "Hi") #tuple записывается в круглых скобках
print(a[0], a[1], a[2])

b = tuple() #изменения по сравнению с аналогичным куском кода для списка минимальны
1 2 Hi
In [85]:
a = (1, 2, "Hi")
a[1] = 4 #так делать нельзя, о чем интерпретатор нам скажет
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-85-c948d5bd30c1> in <module>()
      1 a = (1, 2, "Hi")
----> 2 a[1] = 4 #так делать нельзя, о чем интерпретатор нам скажет

TypeError: 'tuple' object does not support item assignment
In [86]:
a = (1, 2, "Hi")
a.sort() #аналогично нельзя, ведь sort хотел бы изменить a
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-86-cb77c252fb3b> in <module>()
      1 a = (1, 2, "Hi")
----> 2 a.sort() #аналогично нельзя, ведь sort хотел бы изменить a

AttributeError: 'tuple' object has no attribute 'sort'

Tuple так же умеет работать с срезами.

Выше мы встречались с такой конструкцией как параллельное присваивание. Давайте ее немного обобщим.

Раньше у нас параллельное присваивание выглядело так:

a, b = c, d

Но! Если мы вместо двух значений c и d поставим один tuple или list содержащий столько же элементов, сколько и переменных в левой части равенства, то Python проделает аналогичное параллельное присваивание.

In [87]:
a, b = (1, 2) #самый простой случай, когда мы присваиваем в явном виде заданный tuple 
print(a, b)
1 2
In [88]:
a, b, c = [2, "abs", 3] #то же самое но со списком
print(a, b, c)
2 abs 3
In [89]:
tup = (1, 2, 3)
a, b, c = tup #чуть менее тривиальная запись того же самого
print(a, b, c)
1 2 3

Впереди нас ждет еще один кусочек про параллельное присваивание, а пока остановимся.

7.Цикл for

Цикл for имеет в Python свою специфику.

В нашем случае цикл имеет один из двух видов:

  • for переменная in list/tuple
  • for переменная in range(start, end, step)

Рассмотрим примеры.

In [90]:
for i in (2, 3, 5):
    print(i)
2
3
5
In [91]:
t = [3, "ads", 4]
for i in t:
    print(i)
3
ads
4
In [92]:
for i in range(5):
    print(i)
0
1
2
3
4
In [93]:
for i in range(2, 5):
    print(i)
2
3
4
In [94]:
for i in range(2, 10, 3):
    print(i)
2
5
8

Стоить заметить, что поведение параметров range очень похоже на поведение параметров у срезов.

Примеры ниже либо сводят с ума либо показывают, что range во многом похож на list! Но чтобы работали эти примеры нужен Python 3.3 или более новой версии.

In [95]:
r = range(5)

print(r[2], r[-1])
2 4

Аналогично циклу while для цикла for есть оператор break.

In [96]:
for i in range(10):
    print("before", i)
    if i == 2:
        break
    print("after", i)
before 0
after 0
before 1
after 1
before 2

В Python у цикла for есть возможность написать ветку else. Это будет работать так: если цикл был завершен при помощи break, то ветка else выполнена не будет, в противном случае, после выполнения цикла она будет выполнена.

Достаточно странная возможность, чтобы понять как это можно использовать, решим задачу. Дан список, нужно проверить встречается ли в нем $-1$, если встречается, вывести "YES", иначе "NO". (Мы еще не умеем считывать целиком список, поэтому пока зададим его в коде программы.)

In [97]:
l = [1, 2, 3, 4, 5, 10, 1, 5, -1, 10, 12]

for i in l:
    if i == -1:
        print("YES")
        break
else:
    print("NO")
YES
In [98]:
l = [1, 2, 3, 4, 5, 10, 1, 5, 10, 12]

for i in l:
    if i == -1:
        print("YES")
        break
else:
    print("NO")
NO

Такая реализация иногда заметно проще, чем заводить отдельную переменную для флага или писать if...else

8.Строки

Мы уже раньше много раз встречались со строками, задавая их, как правило в явном виде в кавычках. Даже много чего делали с ними: выводили, даже чуть-чуть форматировали. Давайте подробнее обсудим, что можно делать со строками средствами Python.

In [99]:
a = "abc"
b = "edf"
print(a) #просто вывести
print(a * 2) #строки можно естественным образом умножать на целое число
print(a + b) #строки можно складывать
print(a[0], a[-1]) #можно обращаться к элементам строки
abc
abcabc
abcedf
a c
In [100]:
a = "abc"
a[0] = 'f' #строки неизменяемые как и tuple
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-100-3a1b2fcf3362> in <module>()
      1 a = "abc"
----> 2 a[0] = 'f' #строки неизменяемые как и tuple

TypeError: 'str' object does not support item assignment
In [101]:
a = 124 #число
b = str(a) #можно число преобразовать в строчку
print(a, type(a))
print(b, type(b))
124 <class 'int'>
124 <class 'str'>

Выше мы использовали функцию type, с ее помощью очень удобно узнавать тип какой-либо переменной. Она вряд ли вам понадобится на контесте, но иногда может пригодиться для целей отладки.

In [102]:
a = int("1234")
print(a, type(a)) #помните строчку int(input()), там нет никакой магии, мы просто преобразовывали строку к числу
1234 <class 'int'>
In [103]:
a = input()
print(a, type(a)) #функция input просто считывает строчку до перевода строки, все очень просто
132
132 <class 'str'>

Как было сказано выше, строки неизменяемые, но достаточно часто встречается ситуация, когда нам нужно изменить один символ в строке. В таких случаях преобразуют строку к списку и получают список символов, то есть строк состоящих из одного символа, изменяют один элемент списка, что мы уже научились делать, а потом список строк склеивают в одну большую строку. Давайте подробнее посмотрим, как все это делается.

In [104]:
a = "long string" #у нас есть строка, мы хотим уметь ее изменять
print(a)

l = list(a) #сделаем из строки список символов
print(l)

l[2] = "!" #изменим один элемент списка
print(l) 
long string
['l', 'o', 'n', 'g', ' ', 's', 't', 'r', 'i', 'n', 'g']
['l', 'o', '!', 'g', ' ', 's', 't', 'r', 'i', 'n', 'g']

В предыдущем кусочке мы научились преобразовывать строку к списку символов и изменять один символ. Теперь нам нужно научиться из списка символов делать одну большую строку.

Для этого в Python у строки есть метод join.

s.join(l) - вернет строку, в которой все элементы списка $l$ записаны через разделитель(строку) $s$.

In [105]:
print("#".join(["1", "2", "3"])) #запишет "1" "2" "3" через разделительную строку "#" 
1#2#3
In [106]:
print("".join(["1", "2", "3"])) #запишет "1" "2" "3" через пустую разделительную строку 
123

Способом выше как раз и делается, что нам нужно. Давайте теперь целиком напишем программу, которая меняет в считанной строке второй элемент на символ "!".

In [107]:
s = input()
l = list(s)
l[1] = "!" #первый символ имеет индекс 0, второй символ имеет индекс 1
s = "".join(l)
print(s)
123456
1!3456

Так же пока мы не умеем выводить список строк через пробел, это так же делается с помощью метода join.

Есть метод противоположный методу join - это split, он разбивает строку по разделяющей строке и возвращает список строк.

In [108]:
print("1#2#3".split("#")) #разобьет строку по символу "#"
['1', '2', '3']
In [109]:
print("1 2 3        fasd".split()) #split без параметров разбивает строку по пробельным символам
['1', '2', '3', 'fasd']
In [110]:
print("1abc2abcd3".split("abc")) #строка разделитель может стоять более чем из одной буквы
['1', '2', 'd3']

9.Генераторы списков

Иногда возникает необходимость создать список с определенными значениями элементов. Например, предподсчитать квадраты чисел или получить список вида [1, 2, 3, 4, 5, 6, ...], или даже просто получить список заполненный нулями.

Самый простой способ это с помощью метода append добавлять в конец списка нужные элементы, например как сделано в коде ниже.

In [111]:
l = list()

for i in range(10):
    l.append(i**2)
    
print(l)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Конечно, в Python существует более простой способ делать подобные вещи, он называется генератор списка. Для понимания его можно рассматривать как сокращение записи с for, но, формально, он сокращением не является, это просто отдельная конструкция.

In [112]:
l = [i**2 for i in range(10)]
print(l) #этот код делает то же самое, что и код выше
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Как можно попытаться запомнить конструкцию:

имя_списка = [то_что_будет добавляться в конец for переменная in что-то]

In [113]:
l = [0 for i in range(10)] #список длины 10 из нулей
print(l)

l1 = [0] * 10 #списки можно как и строки умножать на число, но этот способ имеет свои особенности, лучше генератор
print(l1)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
In [114]:
l = [2**i for i in range(10)] #список длины 10 из степеней двоек
print(l)
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

На самом деле генераторы умеют "сокращать" еще более сложную запись. Посмотрим на пример ниже.

In [115]:
l = list()

for i in range(10):
    if i % 2 == 1:
        l.append(i**2)
    
print(l) #в l квадраты нечетных чисел
[1, 9, 25, 49, 81]
In [116]:
l = [i**2 for i in range(10) if i % 2 == 1]
print(l)
[1, 9, 25, 49, 81]

В конце генератора можно написать условие, при выполнении которого элементы будут добавляться.

10.Считывание

Как вы могли заметить, мы так и не научились считывать два числа из одной строки. Это одна из немногих вещей, которая в Python чуть-чуть сложнее, чем в более привычных языках. Сейчас нам понадобится все, что мы изучили выше.

In [117]:
a, b = [int(i) for i in input().split()] #так считываются 2 целых числа из одной строки
print(a, type(a))
print(b, type(b))
12 34
12 <class 'int'>
34 <class 'int'>

Что происходит при выполнении этого кода:

  1. Вызывается функция input и считывается одно строка.
  2. Для считанной строки вызывается метод split и разбивает ее по пробелам. Наши числа как раз и были записаны через пробел.
  3. Метод split вернули список строк, после этого цикл в генераторе списка начинает работать и перебирать элементы.
  4. Перед попадание в итоговый список ко всем элементам применяется функция int.
  5. Происходит параллельное присваивание и переменной a присваивается значение первого числа в строк, переменной b значение второго числа.

Давайте ниже напишем эквивалент этого кода, только без генератора списка. Так писать не нужно, потому что это медленно и на самом деле сложнее.

In [120]:
s = input()

l = s.split()
print(l) #посмотрим, что получилось

ans = list()
for el in l:
    ans.append(int(el))
print(el)

a, b = ans

print(a, type(a))
print(b, type(b))
12 34
['12', '34']
34
12 <class 'int'>
34 <class 'int'>

Как вы можете заметить, этот код делает ровно тоже самое, просто мы все написали длиннее.

Заметим, что ровно таким же способов из строки считывается сколько угодно чисел. Чтобы окончательно разобраться, давайте решим задачу. На вход программе дается строка^ содержащая несколько чисел через пробелы, нужно найти минимум из этих чисел.

In [121]:
l = [int(i) for i in input().split()]
print(min(l))
123 3 2 1 43 321 4523
1

На самом деле все то же самое можно было написать в одну строчку!

In [126]:
print(min([int(i) for i in input().split()]))
324235 432423 3423
3423

Чтобы понять, как выводить список через пробел, напишем программу, которая считывает набор чисел из одной строки и сортирует их по убыванию.

Метод join требует на вход список строк, именно для этого мы и воспользовались генератором. То есть генератор здесь только для того, чтобы преобразовать список чисел в список строк. Посмотрите, это действительно так.

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

На самом деле нам хватает уже того, что мы умеем, разве что иногда хочется выводить числа не через пробел или не делать перевод строки после каждого вызова print. Это делается с помощью параметров sep и end. sep это строка, которую print вставляет между двумя элементами для вывода, по умолчанию пробел, а end это строка, которая записывает в конце после вызова print, по умолчанию это '\n', то есть перевод строки.

Посмотрим на несколько примеров.

In [123]:
print(12, 12, sep=":", end="")
12:12
In [124]:
print(1, 2, 3, sep=", ", end="!")#sep и end могут быть не односимвольными
1, 2, 3!

Кажется, на этом хватит :)