Lists - Learn Python 3 - Snakify

Lesson 7
Списки


1. Списки

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

Раньше мы уже столкнулись с задачей обработки элементов последовательности - например, при вычислении самого большого элемента последовательности. Но мы не сохранили всю последовательность в памяти компьютера. Однако во многих проблемах необходимо сохранить всю последовательность, как если бы нам пришлось распечатывать все элементы последовательности в порядке возрастания («сортировать последовательность»).

Для хранения таких данных в Python вы можете использовать структуру данных, называемую списком (в большинстве языков программирования используется другой термин - «массив»). Список представляет собой последовательность элементов, пронумерованных от 0, точно так же, как символы в строке. Список может быть задан вручную путем перечисления элементов списка в квадратных скобках, например:

Primes = [2, 3, 5, 7, 11, 13]
Rainbow = ['Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet']

Список Primes имеет 6 элементов, а именно: Primes[0] == 2 , Primes[1] == 3 , Primes[2] == 5 , Primes[3] == 7 , Primes[4] == 11 , Primes[5] == 13 . Список Rainbow имеет 7 элементов, каждая из которых является строкой.

Подобно символам в строке, элементы списка также могут иметь отрицательный индекс, например Primes[-1] == 13 , Primes[-6] == 2 . Отрицательный индекс означает, что мы начинаем с последнего элемента и идем влево при чтении списка.

Вы можете получить количество элементов в списке с функцией len (значение длины списка ), например len(Primes) == 6 .

В отличие от строк, элементы списка изменяемы; их можно изменить, назначив им новые значения.

Rainbow = ['Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet']
print(Rainbow[0])
Rainbow[0] = 'red'
print('Print the rainbow')
for i in range(len(Rainbow)):
    print(Rainbow[i])

Рассмотрим несколько способов создания и чтения списков. Прежде всего, вы можете создать пустой список (список без элементов, его длина равна 0), и вы можете добавлять элементы в конец своего списка, используя append . Например, предположим, что программа получает количество элементов в списке n , а затем n элементов списка по одному в отдельной строке. Вот пример входных данных в этом формате:

5
1809
1854
1860
1891
1925
В этом случае вы можете упорядочить чтение из такого списка следующим образом:
a = [] # запустите пустой список
n = int(input()) # читать число элементов в списке
for i in range(n): 
    new_element = int(input()) # читать следующий элемент
    a.append(new_element) # добавить его в список
    # последние две строки могут быть заменены на одну:
    # a.append (интермедиат (вход ()))
print(a)

В показанном примере создается пустой список, затем считывается количество элементов, затем вы читаете элементы списка по очереди и добавляете их в конец. То же самое можно сделать, сохранив переменную n :

a = []
for i in range(int(input())):
    a.append(int(input()))
print(a)

Существует несколько операций, определенных для списков: объединение списков (добавление списков, т.е. «склейка» одного списка в другой) и повторение (умножение списка на число). Например:

a = [1, 2, 3]
b = [4, 5]
c = a + b
d = b * 3
print([7, 8] + [9])
print([0, 1] * 3)

Полученный список c будет равен [1, 2, 3, 4, 5] , а список d будет равен [4, 5, 4, 5, 4, 5] . Это позволяет вам упорядочить процесс чтения списков по-разному: во-первых, рассмотрите размер списка и создайте список из нужного количества элементов, затем пропустите переменную i начиная с номера 0, и внутри цикла прочитайте i элемент списка:

a = [0] * int(input())
for i in range(len(a)):
    a[i] = int(input())

Вы можете печатать элементы списка a с print(a) ; это отображает элементы списка, окруженные квадратными скобками и разделенные запятыми. В общем, это неудобно; в общем, вы собираетесь распечатать все элементы в одной строке или по одному элементу в строке. Вот два примера этого, используя другие формы цикла:

a = [1, 2, 3, 4, 5]
for i in range(len(a)):
    print(a[i])

Здесь индекс i изменяется, затем отображается элемент a[i] .

a = [1, 2, 3, 4, 5]
for elem in a:
    print(elem, end=' ')

В этом примере элементы списка отображаются в одной строке, разделенной пробелами, и это не индекс, который изменяется, а скорее значение самой переменной (например, в цикле for elem in ['red', 'green', 'blue'] variable elem будет принимать значения 'red' , 'green' , 'blue' подряд.

Обратите особое внимание на последний пример! Очень важная часть идеологии Python является for цикла, что обеспечивает удобный способ для перебора всех элементов некоторой последовательности. Здесь Python отличается от Pascal, где вам нужно перебирать индексы элементов, но не над самими элементами.

Последовательности в Python - это строки, списки, значения range() функций range() (это не списки) и некоторые другие объекты.

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

# данный: s = 'ab12c59p7dq'
# вам нужно извлечь цифры из списка s
# сделать так:
# цифры == [1, 2, 5, 9, 7]
s = 'ab12c59p7dq'
digits = []
for symbol in s:
    if '1234567890'.find(symbol) != -1:
        digits.append(int(symbol))
print(digits)
Advertising by Google, may be based on your interests

2. Методы разделения и объединения

Элементы списка могут быть указаны в одной строке, разделенной символом; в этом случае весь список можно прочитать с помощью input() . Затем вы можете использовать метод string split() , который возвращает список строк, возникающих после сокращения начальной строки пробелами. Пример:

# вход представляет собой строку
# 1 2 3
s = input() # s == '1 2 3'
a = s.split() # a == ['1', '2', '3']
print(a)

Если вы запустите эту программу с входными данными 1 2 3 , список a будет равен ['1', '2', '3'] . Обратите внимание, что список будет состоять из строк, а не цифр. Если вы хотите получить список номеров, вам нужно преобразовать элементы списка по одному в целые числа:

a = input().split()
for i in range(len(a)):
    a[i] = int(a[i])
print(a)

Используя специальную магию Python - генераторов - то же самое можно сделать в одной строке:

a = [int(s) for s in input().split()]
print(a)

(Мы объясним, как этот код работает в следующем разделе.) Если вы хотите прочитать список реальных чисел, вам нужно изменить тип int для float .

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

a = '192.168.0.1'.split('.')
print(a)

В Python вы можете отображать список строк, используя однострочные команды. Для этого используется join метода; этот метод имеет один параметр: список строк. Он возвращает строку, полученную конкатенацией данных элементов, и разделитель вставлен между элементами списка; этот разделитель равен строке, на которой применяется метод. Мы знаем, что вы не поняли предыдущее предложение с первого раза. :) Посмотрите на примеры:

a = ['red', 'green', 'blue']
print(' '.join(a))
# возврат красный зеленый синий
print(''.join(a))
# return redgreenblue
print('***'.join(a))
# возвращает красный *** зеленый *** синий

Если список состоит из цифр, вы должны использовать темную магию генераторов. Вот как вы можете распечатать элементы списка, разделенные пробелами:

a = [1, 2, 3]
print(' '.join([str(i) for i in a]))
# следующая строка вызывает ошибку типа,
# поскольку join () может только конкатенировать strs
# print ('.join (a))

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

Advertising by Google, may be based on your interests

3. Генераторы

Чтобы создать список, заполненный идентичными элементами, вы можете использовать повторение списка, например:

n = 5
a = [0] * n
print(a)

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

[expression for variable in sequence]

где variable - это идентификатор некоторой переменной, sequence - это последовательность значений, которая принимает переменную (это может быть список, строка или объект, полученный с использованием range функций), expression - некоторое выражение, обычно в зависимости от переменной используемый в генераторе. Элементы списка будут заполнены в соответствии с этим выражением.

Вот несколько примеров использования генераторов.

Вот как вы создаете список из n нулей с помощью генератора:

a = [0 for i in range(5)]
print(a)

Вот как вы создаете список, заполненный квадратами целых чисел:

n = 5
a = [i ** 2 for i in range(n)]
print(a)

Если вам нужно заполнить список квадратов чисел от 1 до n , вы можете изменить настройки range до range(1, n + 1) :

n = 5
a = [i ** 2 for i in range(1, n + 1)]
print(a)

Вот как вы можете получить список, заполненный случайными числами от 1 до 9 (используя randrange из модуля random ):

from random import randrange
n = 10
a = [randrange(1, 10) for i in range(n)]
print(a)

И в этом примере список будет состоять из строк, считанных со стандартного ввода: во-первых, вам нужно ввести количество элементов списка (это значение будет использоваться как аргумент range функций), второе - это количество строк:

a = [input() for i in range(int(input()))]
print(a)
Advertising by Google, may be based on your interests

4. Ломтики

Со списками и строками вы можете делать срезы. А именно:

A[i:j] slice ji элементы A[i] , A[i+1] , ..., A[j-1] .

A[i:j:-1] среза ij элементов 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]
print(A)

Здесь мы получили список [1, 2, 3, 4, 5] , а затем попытаемся заменить два элемента среза A[2:4] новым списком из трех элементов. Полученный список выглядит следующим образом: [1, 2, 7, 8, 9, 5] .

A = [1, 2, 3, 4, 5, 6, 7]
A[::-2] = [10, 20, 30, 40]
print(A)

И здесь результирующий список будет [40, 2, 30, 4, 20, 6, 10] . Причина в том, что A[::-2] - это список элементов A[-1] , A[-3] , A[-5] , A[-7] и что элементы назначены на 10, 20, 30, 40, соответственно.

Если для прерывистого среза (то есть среза с шагом k , k > 1 ) присваивается новое значение, то число элементов в старом и новом срезах обязательно совпадает, в противном случае возникает ошибка ValueError .

Обратите внимание, что A[i] - это элемент списка, а не фрагмент!

Advertising by Google, may be based on your interests

5. Операции над списками

Вы можете легко выполнять множество операций со списками.

x в A
Проверьте, есть ли элемент в списке. Возвращает True или False
x не в A
То же, что и не (x в A)
мин (А)
Самый маленький элемент списка
макс (А)
Самый большой элемент в списке
A.index (х)
Индекс первого вхождения элемента x в список; в его отсутствие генерирует исключение ValueError
A.count (х)
Количество вхождений элемента x в список
Advertising by Google, may be based on your interests