Со списками, так же как и со строками, можно делать срезы. А именно:
A[i:j] срез из j-i элементов
A[i], A[i+1], ..., A[j-1].
A[i:j:-1] срез из i-j элементов
A[i], A[i-1], ..., A[j+1]
(то есть меняется порядок элементов).
A[i:j:k] срез с шагом k:
A[i], A[i+k], A[i+2*k],... .
Если значение k<0, то элементы идут в противоположном порядке.
Каждое из чисел i или j может отсутствовать,
что означает «начало строки» или «конец строки»
Списки, в отличии от строк, являются изменяемыми объектами:
можно отдельному элементу списка присвоить новое значение. Но можно менять и целиком
срезы. Например:
A = [1, 2, 3, 4, 5]
A[2:4] = [7, 8, 9]
Получится список, у которого вместо двух элементов среза A[2:4]
вставлен новый список уже из трех элементов. Теперь список стал равен
[1, 2, 7, 8, 9, 5].
Получится список [40, 2, 30, 4, 20, 6, 10]. Здесь
A[::-2] — это список из элементов
A[-1], A[-3], A[-5], A[-7],
которым присваиваются значения 10, 20, 30, 40 соответственно.
Если не непрерывному срезу (то есть срезу с шагом k, отличному
от 1), присвоить новое значение, то количество элементов в старом и новом срезе
обязательно должно совпадать, в противном случае произойдет ошибка ValueError.
Обратите внимание, A[i] — это элемент списка, а не срез!
Если каждый элемент списка определяется по достаточно простой формуле (или выражается достаточно простым образом через элементы другого списка), то для его создания удобно использовать генераторы списков (list comprehension): выражения, позволяющие заполнить список некоторой формулой.
Общий вид генератора следующий:
[ выражение for переменная in что-то_итерируемое]
Также генератор может быть усложнён, если добавить дополнительное условие:
[ выражение for переменная in что-то_итерируемое if что_проверить]
Здесь переменная — идентификатор некоторой
переменной; что-то_итерируемое — итерируемый объект, из которого извлекаются значения (например, список или range);
выражение — некоторое выражение, которым будут заполнены
элементы списка, как правило, зависящее от использованной в генераторе переменной;
что_проверить — необязательное условие, выполнение которого необходимо для того, элемент был добавлен.
Например, если нужно выбрать все числа, делящиеся на 7 в некотором списке, то это можно сделать так:
my_list = [10, 53, 14, 53, 88, 43, 89, 84, 41, 21, 25, 25, 63, 74, 50, 72, 18, 57, 59, 92]
nums_0_mod_7 = [x for x in my_list if x % 7 == 0]
# Если нужно их сразу вывести:print(' '.join([str(x) for x in my_list if x % 7 == 0]))
Кстати, каждая строка является итерируемым объектом, который по очереди возвращает свои цифры.
Сумму квадратов цифр числа можно найти так:
my_num = 549523521596
sum_dig_sq = sum([int(d)**2for d instr(my_num)])
Иногда бывает нужно проверить, если в списке хотя бы один какой-нибудь «особый» элемент.
Или проверить, что все элементы списка «хорошие».
Команды all и any позволяют сделать это в одну строчку.
Итак, если имеется какой-нибудь итерируемый объект (например, список), то выражение
all(условие for объект in что-то_итерируемое)
принимает значение True если и только если, условие выполнено для всех объектов в что-то_итерируемое.
any(условие for объект in что-то_итерируемое)
принимает значение True если и только если, условие выполнено хотя бы для одного объекта в что-то_итерируемое.
Например, проверим, что все числа в списке (или хотя бы одно) находятся в диапазоне от 1000 до 9999:
ifall(1000 <= x <= 9999for x in my_list):
print('Все элементы от 1000 до 9999')
ifany(1000 <= x <= 9999for x in my_list):
print('По крайней мере один элемент от 1000 до 9999')
Развёрнутый код для каждой из конструкций:
bad_found = Falsefor x in my_list:
ifnot1000 <= x <= 9999:
bad_found = Truebreakifnot bad_found:
print('Все элементы от 1000 до 9999')
#
good_found = Falsefor x in my_list:
if1000 <= x <= 9999:
good_found = Truebreakif good_found:
print('По крайней мере один элемент от 1000 до 9999')
В питоне True и False можно использовать как числа в арифметических выражениях.
Истина равна единице, а ложь — нулю.
Это позволяет писать кратко некоторые вещи.
Например, пусть у нас есть числа a, b, c, и мы хотим узнать, сколько из них больше нуля.
Вместо громоздкой конструкции
res = 0if a > 0:
res += 1if b > 0:
res += 1if c > 0:
res += 1
можно написать коротко
res = (a > 0) + (b > 0) + (c > 0)
Вместе с генератором списка эта возможность позволяет подсчитывать количество «хороших» элементов в списке в одну строчку.
Например, можно так можно посчитать количество чисел от 1 до 9999, в десятичной записи которых есть цифра 7:
print(sum(['7'instr(i) for i inrange(1, 10000)]))
Как это работает? Конструкция '7' in str(i) возвращает True, если цифра 7 есть в записи числа i, и False иначе. При этом число i пробегает все значения от 1 до 9999: ('7' in str(i) for i in range(1, 10000)). И наконец функция sum вычисляет сумму всех этих выражений. Так как False равен 0, то сумма равна в точности количеству чисел от 1 до 9999, в десятичной записи которых есть цифра 7.
Развёрнутый код для этой конструкции получается таким:
В языке питон есть тернарная условная операция, подобная [expression]?[on_true]:[on_false] в языке си.
Тернарная условная операция принимает на вход три параметра: логическое выражение и два значения,
и возвращает первое или второе значение в зависимости от значения логического выражения.
Его синтаксис такой:
Большинство упражнений этого листка копирует задачи предыдущего листка. Но в предыдущем листке
задачи необходимо решать без использования срезов, дополнительных списков, методов списков.
В этом же листке, наоборот, нельзя использовать циклы. Используйте срезы и методы.
Для многих упражнений написано, какое наибольшее число строк может быть в программе. Как правило, ограничения
будут или в одну строку, или в три строки.
Если программа решается в одну строку, то необходимо использовать функции внутри функций. Например, вот так
можно вычислить сумму всех чисел, введенных в строку, используя стандартную функцию sum:
print(sum(map(int, input().split())))
Обратите внимание, в однострочном решении нельзя сохранять список в переменной - нужно сразу же его обработать и
вывести результат.
Решение в две строки, как правило, должно иметь следующий вид:
A = input().split()
print(' '.join(...))
При этом зачастую не требуется преобразовывать элементы списка к типу int.
Решение в три строки, как правило, должно иметь следующий вид:
A = input().split()
A = ...
print(' '.join(map(str, ...)))
Первая строка - считывание списка. Вторая строка - цикл for
и считывание числа повторений. Третья строка - модификация списка в цикле.
Четвертая строка - вывод результата.
Первая строка - считывание данных. Вторая строка - создание списка.
Третья строка - цикл for. Четвертая строка - добавление нового элемента в список.
Пятая строка - вывод результата. Для суммирования среза списка используйте функцию sum.
Билет с шестизначным номером называется «счастливым», если сумма первых трёх цифр совпадает с суммой трёх последних.
Посчитайте количество счастливых билетов.
Решите эту задачу в одну строчку
Если бы мы считали четырёхзначные билеты, то ответ был бы таким: