Как правило, первая программа которую пишут на языке - это "Hello world!". Ниже приведен полный код этой программы на языке Python 3.
print("Hello world!")
Здесь мы в первый раз сталкиваемся с функцией print
, это функция вывода. В простейшем случае, чтобы написать что-нибудь на экран нам достаточно написать print()
и внутри скобочек, то что мы хотим вывести. Каждый такой вызов print
печатает на отдельной строчке.
Первый тип данных, с которым мы познакомимся, будет строка (str
). "Hello world!" является строкой.
Строки в python можно задавать также с помощью одинарных кавычек:
print('Hello world!')
print(10)
print(2 + 2)
print(11, 11)
print("Hi!", 42, 12.5)
Какие ещё типы данных, помимо строки, есть в коде выше?
Целое число (int
), дробное число (float
).
Язык программирования python является интерпретируемым языком, в отличие от Pascal или C/C++,
являющихся компилируемыми.
В компилируемых языках написанный код переводится с помощью специальной программы, называемой компилятором, в другой код (процесс перевода --- компиляция), более понятный машине, а затем уже исполняется этот новый код.
В интерпретируемых языках написанный код никуда не переводится, а выполняется построчно с помощью специальной программы, называемой интерпретатором (в нашем случае, это python3). Увидели строчку --- выполнили.
Как следствие этого, если вы писали до этого на компилируемых языках, то при попытке компиляции вам сразу
выдавались все ошибки в коде, если они были. И программа не запускалась до тех пор, пока вы не устраните все ошибки.
В интепретируемых языках вы увидите ошибку только в тот момент, когда дойдете до нее. То есть часть кода может выполнится
успешно, и выполнение остановится, как только где-нибудь вы допустили ошибку.
Конечно, как в любом языке программирования, в Python есть переменные. Самое первое, что мы научимся делать -- это присваивать переменной значение. Ниже показано, как это сделать.
a = 5
b = 7 + 3
print("a + b =", a + b)
c = a + b
print(' "c =" ', c) # что будет напечатано?
В этом куске кода выше есть как минимум одна новая вещь: комментарий, он начинается с символа #
и продолжается до конца строки.
some_string = "string variable"
print("some_string =", some_string)
"""
сами строки
не выводятся с кавычками
"""
В примере выше показано, как можно писать многострочные комментарии. Вместо двойных кавычек также можно использовать одинарные.
Как вы заметили, в отличие от С/С++ и Pascal, мы при объявлении переменной не задавали ее тип. Все очень просто: в Python у переменной нет типа, подобное свойство языка называют динамической (утиной) типизацией. Определение типа переменной основано на свойствах переменной.
Если это выглядит как утка, плавает как утка и крякает как утка, то это возможно и есть утка.
Пример ниже демонстрирует это свойство чуть-чуть подробнее.
a = 5
print(a) # python сам определяет, что это целое число (int)
a = "a is string now!"
print(a) # теперь python понимает, что это строка (str)
Подобное бывает очень удобно, но вынуждает отдельно следить за тем, какой тип у значения этой переменной.
Какие типы у переменных $a$ и $b$? Что будет выведено ниже?
a = 5
b = "5"
print(a + b)
Будет ошибка, так как python не позвоялет складывать целые числа и строки с помощью +.
Давайте научимся складывать, умножать, вычитать и производить другие операции с целыми или вещественными числами. Стоит понимать, что целое число и вещественное число это совсем разные вещи для компьютера.
Список основных бинарных (требующих 2-ух переменных) арифметических действий, которые вам понадобятся:
a = 1
b = 2
print(a + b)
a = 2.0
b = 1
print(a + b)
a = 4
b = 5
print(a - b)
a = 3.0
b = 4
print(a - b)
a = 2
b = 4
print(a * b)
a = 2.1
b = 4
print(a * b)
a = -2.1
b = 4
print(a * b)
a = 10
b = 2
print(a // b)
a = 10
b = 3
print(a // b)
a = -10
b = 3
print(a // b)
Стоит заметить, что по математическим правилам x = y $\cdot$ b + r, где r --- остаток при делении числа x на y и r $\ge$ 0. Отсюда следует, что y = x // b. В примере выше: -10 = -4 $\cdot$ 3 + 2
a = 10
b = 3
print(a / b)
a = 10
b = 2
print(a / b)
Даже если r = 0, то результат всё равно будет вещественным числом (float
)
a = 10
b = 2
print(a % b)
a = 10
b = 3
print(a % b)
a = 10
b = 3.5
print(a % b)
a = -10
b = 3
print(a % b)
Здесь как раз видно, что r = 2
a = 2
b = 2
print(a ** b)
a = -2
b = 2
print(a ** b)
a = 2
b = -2
print(a ** b)
a = 2.5
b = 2
print(a ** b)
a = 4
b = 0.5
print(a ** b)
Кто не знает: $\sqrt{a} = a^{\tfrac{1}{2}} = a^{0.5}$
a = -4
b = 0.5
print(a ** b)
В школе наверное рассказывали, что извелкать корни из отрицательных чисел нельзя. Так вот, это не совсем правда, всё-таки можно. Только получим мы не привычные нам вещественные числа, а так называемые комплексные числа. Если вдруг вы в программе получили такую страшную бяку, то не пугайтесь :) В частности, это скорее всего означает, что вы взяли корень из отрицательного числа и следует искать ошибку (баг) в коде. В задачах на контесте комплексных чисел не будет.
Здесь мы также увидели некоторое особенное число 1.2246467991473532e-16. Что же это такое?
Запись <число>
e<степень>
= <число>
$\cdot 10^{\text{<степень>}}$
Чему же равно 1.2246467991473532e-16?
a = -4.2
b = -0.5
print(a ** b)
Так же существует специальный операторы позволяющие сократить записи вида: a = a + 5. Все эти операторы записываются как "оператор=", ниже несколько примеров.
a = 1
a += 2 # эквивалент а = а + 2
print(a)
a = 3
b = 2
a *= b # эквивалент а = а * b
print(a)
a = 3
b = 2
a **= b # эквивалент а = а ** b
print(a)
Отдельно обратим внинамние на то, как пишутся арифметические опреации. Вокруг любой арифметической операции ставится по одному пробелу. Например, x+y
--- неправильно, а x + y
--- правильно. Это часть соглашения о стиле написания кода на
python PEP8.
Думаю, всем понятно, как работает оператор if, ниже несколько примеров, чтобы разобраться с синтаксисом python.
if 5 < 3:
print("Правда")
else:
print("Ложь")
После условия в if
или после else
ставится двоеточие :. Это часть синтаксиса python.
Все, что будет выполняться после if
должно идти с отступом 4 пробела (или один tab, но нельзя их смешивать! используйте пробелы или настройте в среде конвертацию таба в пробелы) относительно предыдущей строки.
Аналогично с else
. Это демонстрирует пример ниже.
if 10 > 5:
print("1")
print("2")
if 5 < 4:
print("3")
print("4")
else:
print("5")
else:
print("6")
По отступам очень удобно отслеживать, какой else
к какому if
относится.
Если не ставить двоеточие или отступы, то программа будет выдавать ошибку и не запустится.
if 6 > 5
print("Пропущено двоеточие!")
if 6 > 5:
print("Пропущен отступ!")
Некоторые среды программирования, такие как, Wing Ide, в котором мы будем работать, умеют автоматически расставлять отступы там, где это необходимо.
if 9 * 7 ** 2 > 8 * 5 ** 2:
print("Правда")
else:
print("Ложь")
if True:
print("Ветка if")
else:
print("Ветка else")
if False:
print("Ветка if")
else:
print("Ветка else")
В python существуют 2 логических типа: True
и False
. Такие типы нызвают булевскими (bool
).
Конструкция elif
позволяет рассматривать множественные случаи без вложенных if ... else
.
if False:
print("Ветка if")
elif True:
print("Ветка elif")
else:
print("Ветка else")
Что будет напечатано выше?
Понятно, что после if может стоять не только значение True или False. Посмотрим, что делает Python, если после if стоит нечто более странное?
Одни типы данных могут приводиться к другим, если это возможно (если python позволяет). Такое преобразование называется приведением типов, или, на слэнге, прикастовыванием (от англ. cast --- приведение).
0 --> False
if 0:
print("Ветка if")
else:
print("Ветка else")
Любое другое число (в том числе и нецелое), отличное от 0 --> True
if 5:
print("Ветка if")
else:
print("Ветка else")
if 3.5:
print("Ветка if")
else:
print("Ветка else")
if 0.0:
print("Ветка if")
else:
print("Ветка else")
if -1:
print("Ветка if")
else:
print("Ветка else")
Пустая строка ""
--> False
if "":
print("Ветка if")
else:
print("Ветка else")
Непустая строка --> True
if "abc":
print("Ветка if")
else:
print("Ветка else")
if "''":
print("Ветка if")
else:
print("Ветка else")
Посмотрим, как устроены логические операции и операции сравнения в Python.
Вот список тех из них, которыми вы будете пользоваться наиболее часто:
==
!=
<
<=
>
>=
or
and
not
Рассмотрим несколько примеров.
print(5 > 2)
print(not 5 > 2)
a = 5
b = 2
print(a > b and a >= b)
a = 5
b = 2
print(True and a > 2)
a = 5
b = 2
print(False or b >= 2)
a = 5
b = 2
print(b == a)
a = 5
b = 2
print(b != a)
А вот так писать плохо и бессмысленно:
bool_var = True
if bool_var == True:
print("ай-ай")
if bool_var:
print("Так хорошо")
bool_var = False
if not bool_var:
print("И так тоже")
Конечно, в условии после if
чаще всего и приходится использовать логические операции. В качестве примера, давайте напишем программу, проверяющую является ли данный год високосным.
year = 2015
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print("YES")
else:
print("NO")
Единственная проблема у кода выше - это невозможность считать год с клавиатуры, как можно заметить, мы задали его в явном виде. Для решения этой проблемы нам понадобится функция input
, она считывает строчку (до перевода строки) из stdin
(стандартного потока ввода, который обычно связан с клавиатурой). Также нам понадобится функция int
, она преобразует число записанное в виде строки в число. Далее, на примере среды Wing, мы подробнее разберем, откуда все считывается и куда выводится.
year = int(input())
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print("YES")
else:
print("NO")
Очень часто случается, что нам надо повторить некоторые действия определенное число раз. Для этого в python есть разные типы циклов.
Самый просто устроенный цикл - while
. Он работает точно так же как и в остальных языках программирования.
i = 0
while i < 5:
i += 1
print(i)
Естественно, после while
может стоять любое условие.
Также есть оператор break
, он заканчивает выполнение цикла по достижению break
.
i = 0
while True:
print("before", i)
if i == 2:
break
print("after", i)
i += 1
Для примера давайте напишем программу, которая выводит наименьшую степень двойки, которая больше заданного числа $n$.
n = int(input())
cp, i = 1, 0
while n >= cp:
cp *= 2
i += 1
print("cp = %d, i = %d" % (cp, i)) # это более удобный способ форматирования строк, ниже несколько комментариев про него
В задаче выше мы воспользовались несколькими новыми вещами.
Во-первых, конструкция вида a, b = c, d
, называется параллельным присваиванием. В этом случае переменной a
будет присвоено значение c
, а переменной b
--- значение d
. В некоторых ситуациях это бывает очень удобно.
Во-вторых, если нам нужно получить строку, содержащую несколько целых чисел с некоторым форматированием, то это можно сделать с помощью конструкции подобной конструкции выше. Формальное объяснение этой конструкции достаточно громоздко, давайте посмотрим на несколько примеров.
print("I'am %d years old." % 19)
%d
указывает на то, что на месте %d
должно стоять число, идущее после %
(в данном случае это 19).
В примере со степенью надо было подставить 2 числа, для этого мы их объединили в скобки. Если написать без них,
то будет ошибка, так как ожидается, что должно подставить 2 значения, а дано только одно. Более точное объяснение скобкам
будет ниже.
print("2 * 2 = %d" % (2 * 2)) # самый простой пример просто вставляющий целое число в нужное место
Форматирование строк --- мощный и гибкий инструмент. Можно задавать различные параметры, например, для подставляемых чисел.
Например, в следующем примере, конструкция %02d
означает: подставить число, если оно меньше двух знаков, то заполнить пространство перед ним нулями так, чтобы суммарно получилось два знака.
print("%02d:%02d" % (15, 2)) # немного форматирования самого числа
Несколько общих слов. List это некоторое подобие массива в "привычных" вам языках программирования лишь с тем отличием, что в list
могут храниться элементы разных типов. Давайте попробуем разобраться на примерах.
a = [1, 2, "Hi"] # мы создали список и присвоили переменной а этот список
print(a[0], a[1], a[2]) # так обращаться к элементам списка, элементы индексируются с нуля
b = list() # таким образом можно создать пустой список
c = [] # пустой список также можно создать и таким способом
В Python есть отрицательная индексация. $-1$ элемент это последний элемент, $-2$ элемент это предпоследний элемент списка и так далее. После примеров ниже должно стать совсем понятно.
a = [1, 2, "Hi"]
print(a[-2])
b = ["a", 1, 2, 3, 4, "b", -10, [1, 2, 3], 3.4, "!!!"] # элементом списка может быть список
print(b[-3])
a = [1, 2, "Hi"]
a[1] = 4 # можно изменить отдельный элемент
print(a) # можно вывести весь список
Бывает такое, что нам нужна только некоторая часть списка, например все элементы с $5$ по $10$, или все элементы с четными индексами. Подобное можно сделать с помощью срезов.
Срез задается одним из нескольких способов:
Нужно понимать, что любой из параметров может быть опущен так, например, срез a[::] будет содержать просто весь список a.
print([1, 2, 3, 4, 5, 6, 7, 8][:5])
print([1, 2, 3, 4, 5, 6, 7, 8][1:7:2])
print([1, 2, 3, 4, 5, 6, 7, 8][:0])
print([1, 2, 3, 4, 5, 6, 7, 8][::2])
print([1, 2, 3, 4, 5, 6, 7, 8][::-1])
print([1, 2, 3, 4, 5, 6, 7, 8][2::-1])
Кстати, как вы думаете, что будет выведено ниже?
if []:
print("Ветка if")
else:
print("Ветка else")
if not []:
print("Ветка if")
else:
print("Ветка else")
if [2, 3, 4]:
print("Ветка if")
else:
print("Ветка else")
В списках все точно так же, как и со строками: пустой список []
--> False
, непустой -->True
.
Что будет выведено ниже?
if [[]]:
print("Ветка if")
else:
print("Ветка else")
Несколько необычных примеров:
print("abc" and [1, 2, 34])
print("abc" < [1, 2])
print("abc" == [1, 2])
print("abc" != [1, 2])
Давайте немного подробнее поговорим о присваивании списков, с этим в Python есть несколько сложностей.
Как уже было сказано ранее, Python интерпретируемый язык. Во время выполнения он должен хранить все данные которые у вас есть в программе, поэтому у интерпретатора во время выполнения хранится множество существующих объектов, и переменная это всего лишь ссылка на объект, который хранит интепретатор.
Давайте чуть-чуть подробнее изучим, как устроен лист с учетом ссылочного устройства.
a = [1, 2, 3, 4] # а - ссылка на лист, каждый элемент листа это ссылка на элементы 1, 2, 3, 4
b = a # b - ссылка теперь на тот же лист
c = "abc"
d = 5
print("id(a) = %d, id(b) = %d" % (id(a), id(b))) # в Python у каждого объекта есть свой id
# это некоторое уникальное число сопоставленное объекту
a[0] = -1
print("b =", b)
Также для списка есть набор удобных функций уже встроенных в Python, которые иногда упрощают жизнь. Давайте посмотрим на некоторые из них.
l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
print(min(l))
# не стоит думать, что min можно брать только от list или tuple, конечно, существует min от двух элементов
print(min(12, 10))
print(sum([2, 3, 11, 1])) # эта функция суммирует все числа в list или tuple
l = [1, 2, 3]
l.append(4) # метод append добавляет элемент в конец списка
print(l)
l.pop() # метод pop удаляет из списка последний элемент
print(l)
l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
print(l.index(3)) # заметьте, что в списке l у нас две тройки и index возвращает индекс первой из них
l = [1, 2, -1, 3, 2, -2, 1, 5, 7, 3]
print(l.index(115)) # если элемента нет в списке, то произойдет ошибка выполнения
l = [1, 2, 4, 5]
l.insert(2, 3) # метод insert(idx, el) вставляет элемент el на место idx.
print(l)
Так же есть удобный метод sort
, он сортирует список по невозрастанию.
a = [3, 2, 4, 1, 2]
a.sort()
print(a)
Еще одна приятная функция это reverse
, она, как следует из названия, переворачивает список.
a = [1, 4, 2, 5, 2]
a.reverse()
print(a)
А как еще можно перевернуть список?
a = [1, 4, 2, 5, 2]
a = a[::-1]
print(a)
Списки также можно складывать друг с другом:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)
У списка можно узнать его длину:
a = [1, 3, 6]
print(len(a))
Tuple
почти ничем не отличает от list
, только он неизменяемый. То есть нельзя взять и изменить один элемент. Во всем остальном они будут идентичны.
a = (1, 2, "Hi") # tuple записывается в круглых скобках
print(a[0], a[1], a[2])
b = tuple() # изменения по сравнению с аналогичным куском кода для списка минимальны
с = (3,)
a = (1, 2, "Hi")
a[1] = 4 # так делать нельзя, о чем интерпретатор нам скажет
a = (1, 2, "Hi")
a.sort() # аналогично нельзя, ведь sort хотел бы изменить a
Tuple
так же умеет работать с срезами.
Выше мы встречались с такой конструкцией как параллельное присваивание. Давайте ее немного обобщим.
Раньше у нас параллельное присваивание выглядело так:
a, b = c, d
Но! Если мы вместо двух значений c
и d
поставим один tuple
или list
содержащий столько же элементов, сколько и переменных в левой части равенства, то Python проделает аналогичное параллельное присваивание.
a, b = (1, 2) # самый простой случай, когда мы присваиваем в явном виде заданный tuple
print(a, b)
a, b, c = [2, "abs", 3] # то же самое, но со списком
print(a, b, c)
tup = (1, 2, 3)
a, b, c = tup # чуть менее тривиальная запись того же самого
print(a, b, c)
Впереди нас ждет еще один кусочек про параллельное присваивание, а пока остановимся.
Цикл for
имеет в Python свою специфику.
В нашем случае цикл имеет один из двух видов:
for
переменная in list
/tuple
for
переменная in range(start, end, step)
Рассмотрим примеры.
for i in (2, 3, 5):
print(i)
t = [3, "ads", 4]
for i in t:
print(i)
for i in range(5):
print(i)
for i in range(2, 5):
print(i)
for i in range(2, 10, 3):
print(i)
Стоить заметить, что поведение параметров range
(некоторый объект) очень похоже на поведение параметров у срезов.
Примеры ниже либо сводят с ума либо показывают, что range
во многом похож на list
! Но чтобы работали эти примеры нужен Python 3.3 или более новой версии.
r = range(5)
print(r[2], r[-1])
Аналогично циклу while
для цикла for
есть оператор break
.
for i in range(10):
print("before", i)
if i == 2:
break
print("after", i)
В Python у цикла for
есть возможность написать ветку else
. Это будет работать так:
если цикл был завершен при помощи break
, то ветка else
выполнена не будет, в противном случае, после выполнения цикла она будет выполнена.
Достаточно странная возможность, чтобы понять как это можно использовать, решим задачу. Дан список, нужно проверить встречается ли в нем $-1$, если встречается, вывести "YES", иначе "NO". (Мы еще не умеем считывать целиком список, поэтому пока зададим его в коде программы.)
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")
l = [1, 2, 3, 4, 5, 10, 1, 5, 10, 12]
for i in l:
if i == -1:
print("YES")
break
else:
print("NO")
Такая реализация иногда заметно проще, чем заводить отдельную переменную для флага или писать if...else
.
Мы уже раньше много раз встречались со строками, задавая их, как правило в явном виде в кавычках. Даже много чего делали с ними: выводили, даже чуть-чуть форматировали. Давайте подробнее обсудим, что можно делать со строками средствами Python.
a = "abc"
b = "edf"
print(a) # просто вывести
print(a * 2) # строки можно естественным образом умножать на целое число
print(a + b) # строки можно складывать
print(a[0], a[-1]) # можно обращаться к элементам строки
print(len(a)) # возвращает длину строки
a = "abc"
a[0] = 'f' # строки неизменяемые как и tuple
a = 124 # число
b = str(a) # можно число преобразовать в строку
print(a, type(a))
print(b, type(b))
Выше мы использовали функцию type
, с ее помощью очень удобно узнавать тип какой-либо переменной. Она вряд ли вам понадобится на контесте, но иногда может пригодиться для целей отладки.
a = int("1234")
print(a, type(a)) # помните строчку int(input()), там нет никакой магии, мы просто преобразовывали строку к числу
a = input()
print(a, type(a)) # функция input просто считывает строчку до перевода строки, все очень просто
Как было сказано выше, строки неизменяемые, но достаточно часто встречается ситуация, когда нам нужно изменить один символ в строке. В таких случаях преобразуют строку к списку и получают список символов, то есть строк состоящих из одного символа, изменяют один элемент списка, что мы уже научились делать, а потом список строк склеивают в одну большую строку. Давайте подробнее посмотрим, как все это делается.
a = "long string" # у нас есть строка, мы хотим уметь ее изменять
print(a)
l = list(a) # сделаем из строки список символов
print(l)
l[2] = "!" # изменим один элемент списка
print(l)
В предыдущем кусочке мы научились преобразовывать строку к списку символов и изменять один символ. Теперь нам нужно научиться из списка символов делать одну большую строку.
Для этого в Python у строки есть метод join
.
s.join(l)
- вернет строку, в которой все элементы списка $l$ записаны через разделитель(строку) $s$.
print("#".join(["1", "2", "3"])) # запишет "1" "2" "3" через разделительную строку "#"
print("".join(["1", "2", "3"])) # запишет "1" "2" "3" через пустую разделительную строку
Способом выше как раз и делается, что нам нужно. Давайте теперь целиком напишем программу, которая меняет в считанной строке второй элемент на символ "!".
s = input()
l = list(s)
l[1] = "!" # первый символ имеет индекс 0, второй символ имеет индекс 1
s = "".join(l)
print(s)
Также пока мы не умеем выводить список строк через пробел, это так же делается с помощью метода join
.
Как можно по-другому изменить третий символ в строке?
s = input()
s = s[:2] + "!" + s[4:]
print(s)
Есть метод, противоположный методу join, --- это split, он разбивает строку по разделяющей строке и возвращает список строк.
print("1#2#3".split("#")) # разобьет строку по символу "#"
print("1 2 3 fasd".split()) # split без параметров разбивает строку по пробельным символам
print("1abc2abcd3".split("abc")) # строка-разделитель может стоять более чем из одной буквы
Иногда возникает необходимость создать список с определенными значениями элементов. Например, предподсчитать квадраты чисел или получить список вида [1, 2, 3, 4, 5, 6, ...]
, или даже просто получить список заполненный нулями.
Самый простой способ это с помощью метода append
добавлять в конец списка нужные элементы, например как сделано в коде ниже.
l = list()
for i in range(10):
l.append(i ** 2)
print(l)
Конечно, в Python существует более простой способ делать подобные вещи, он называется генератор списка. Для понимания его можно рассматривать как сокращение записи с for
, но, формально, он сокращением не является, это просто отдельная конструкция.
l = [i ** 2 for i in range(10)]
print(l) # этот код делает то же самое, что и код выше
Как можно попытаться запомнить конструкцию:
имя_списка = [то_что_будет добавляться в конец for переменная in что-то]
l = [0 for i in range(10)] # список длины 10 из нулей
print(l)
l1 = [0] * 10 # списки можно как и строки умножать на число, но этот способ имеет свои особенности, лучше генератор
print(l1)
l = [2 ** i for i in range(10)] # список длины 10 из степеней двоек
print(l)
На самом деле генераторы умеют "сокращать" еще более сложную запись. Посмотрим на пример ниже.
l = list()
for i in range(10):
if i % 2 == 1:
l.append(i ** 2)
print(l) # в l квадраты нечетных чисел
l = [i ** 2 for i in range(10) if i % 2 == 1]
print(l)
В конце генератора можно написать условие, при выполнении которого элементы будут добавляться.
Также можно делать со списками и строками:
a = [i for i in [1, 2, 3, 4, 5, 6] if i % 2 == 0]
print(a)
b = [c for c in "abcdef"]
print(b)
Как вы могли заметить, мы так и не научились считывать два числа из одной строки. Это одна из немногих вещей, которая в Python чуть-чуть сложнее, чем в более привычных языках. Сейчас нам понадобится все, что мы изучили выше.
a, b = [int(i) for i in input().split()] # так считываются 2 целых числа из одной строки
print(a, type(a))
print(b, type(b))
Что происходит при выполнении этого кода:
input
и считывается одно строка.split
и разбивает ее по пробелам. Наши числа как раз и были записаны через пробел.split
вернули список строк, после этого цикл в генераторе списка начинает работать и перебирать элементы.int
.a
присваивается значение первого числа в строк, переменной b
значение второго числа.Давайте ниже напишем эквивалент этого кода, только без генератора списка. Так писать не нужно, потому что это медленно и на самом деле сложнее.
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))
Как вы можете заметить, этот код делает ровно тоже самое, просто мы все написали длиннее.
Заметим, что ровно таким же способов из строки считывается сколько угодно чисел. Чтобы окончательно разобраться, давайте решим задачу. На вход программе дается строка, содержащая несколько чисел через пробелы, нужно найти минимум из этих чисел.
l = [int(i) for i in input().split()]
print(min(l))
На самом деле все то же самое можно было написать в одну строчку!
print(min([int(i) for i in input().split()]))
Если вы хотите убрать вокруг строки лишние пробельные символы (что вполне может подаваться на входе), то вам понадобится функция .strip(), применяемая к строке. Рассмотрим пример:
s = " sdf kjk sd "
print(s.split()) # split без параметров умеет разбивать по нескольким пробелам
print(s.split(' '))
s = s.strip()
print(s)
print(s.split(' '))
Чтобы понять, как выводить список через пробел, напишем программу, которая считывает набор чисел из одной строки и сортирует их по убыванию.
a = [int(i) for i in input().strip().split()] # в данном случае strip можно и не писать, так как split без параметров
print(a)
a.sort()
print(a)
for i in a:
print(i)
Другой вариант написания:
a = [int(i) for i in input().split()]
a.sort()
a = [str(i) for i in a]
print(a)
print(' '.join(a))
Метод join
требует на вход список строк, именно для этого мы и воспользовались генератором. То есть генератор здесь только для того, чтобы преобразовать список чисел в список строк. Посмотрите, это действительно так.
На самом деле, мы уже умеем почти все, что нужно чтобы писать простые программы на Python. Для дополнительного удобства, давайте подробнее рассмотрим функцию print
, мы много раз ей пользовались, но подробно не говорили.
На самом деле нам хватает уже того, что мы умеем, разве что иногда хочется выводить числа не через пробел или не делать перевод строки после каждого вызова print
. Это делается с помощью параметров sep
и end
. sep
это строка, которую print
вставляет между двумя элементами для вывода, по умолчанию пробел, а end
это строка, которая записывает в конце после вызова print
, по умолчанию это '\n', то есть перевод строки.
Посмотрим на несколько примеров.
print(12, 12, sep=":", end="")
print(45, 23)
print(1, 2, 3, sep=", ", end="!") # sep и end могут быть не односимвольными
Заметим, что по стилю PEP8 после запятой ставится ровно один проблел, а перед --- ничего не ставится.
Иногда нам хочется использовать какие-то дополнительные функции, которые по умолчанию не встроены в интерпретатор. Для этого люди пишут программы, называемые библиотеками (модулями) , которые содержат часто используемые функции, не встроенные в интерпретатор.
Например, нам хочется поделить число $n$ на некоторое $k$ и округлить его вверх. То есть, например, 2.5 округлить до 3.
from math import ceil
n, k = [int(i) for i in input().split()]
print(n / k)
print(ceil(n / k))
Здесь мы использовали модуль math
и импортировали (взяли, получили) из него только функцию ceil
.
Импортирование модулей всегда пишется в начале программы.
Еще различные варианты написания:
import math
print(math.ceil(5 / 3))
Здесь мы вынужденны писать <имя модуля>.<название функции>
А вот так писать совсем плохо:
from math import *
Такая запись означает: импортируй из math
все, что там есть . Чем это плохо?
Это плохо, потому что имена функций в разных модулях могут пересекаться, что может привести в неожиданному для вас поведению программы. Поэтому предпочтительнее всего использовать второй вариант (import math). Если вы точно уверены, что пересечений имен не будет, то можете использовать первый вариант.
Приведем еще примеры модулей и функций из них:
from math import sqrt
from math import floor
from random import randrange
from random import choice
print(sqrt(4), sqrt(9)) # квадратный корень из неотрицательного числа
print(4 / 3, floor(4 / 3)) # округление вниз
print(randrange(2, 10, 2)) # рандомноe число из последовательности (begin, end, step)
print(choice([4, 8, 2, 7])) # рандомное число из переданной последовательности
print(choice("asd"))
print(choice((-3, -7, -2)))
from math import sqrt
print(sqrt(-1)) # заметим, что здесь будет ошибка, так как sqrt работает только для неотрицательных чисел
a = ("sdfjsdjfksjflksjdklfjsf" + "sjdlfjksfgehrgldfoidg" + "sfsfd" +
"werwerkwer" + "jlsfdsdlf")
print(a)
var = (a * b +
5 * c) # правильно
var = (a * b
+ 5 * c) # неправильно
import
каждого модуля на отдельной строке.a = [ 1,3, 5 ,6 ] # неправильно, пробел после запятой ровно 1, перед запятыми пробелы не нужны. Отступы после [ и
# и перед ] тоже не нужны
a = [1, 3, 5, 6] # правильно
print(a[1]) # правильно
print(a[ 1 ]) # неправильно, пробелы около после [ и перед ] не нужны
print(a [1]) # неправильно, пробел перед [ не нужен
print (a[1]) # неправильно, пробел перед (. Как и для любого вызова функции
if a[1] == 1: # правильно
print("1")
if a[1] == 1 : # неправильно, пробелы пробел перед : не нужен
print("2")
l
, I
, O
как имена переменных. В некоторых шрифтах они похожи на цифры.n
). Имена переменных должны состоять только из маленьких латинских букв.
Несколько слов в имени переменной разделяются_символами_подчеркивания.var1 = 5
var2 = 6
var3 = 9
# что такое var?
# за что она отвечает?
name = "Vasya"
people_count = 23
NAME = "Andrew"
SCHOOL_NAME = "LKSH"
Кажется, на этом хватит:)