Главная страница

Пособие. Пособие по Python. Название Описание


Скачать 0.75 Mb.
НазваниеНазвание Описание
АнкорПособие
Дата05.10.2021
Размер0.75 Mb.
Формат файлаpdf
Имя файлаПособие по Python.pdf
ТипДокументы
#241608
страница3 из 5
1   2   3   4   5
for
city
in
lst:
print
(city)
Смотрите, как это легко и просто делается! Конечно, мы можем распечатать весь контейнер целиком, просто записав:
print
(lst)
Но здесь нет перебора всех элементов, а просто печать содержимого.
Вернемся к циклу. Здесь переменная city будет ссылаться на элементы внутри списка lst. Давайте выведем в консоль дополнительно еще тип выводимого значения:
print
(city
,
type
(city))

Увидим везде строковый тип str. Но раз city ссылается на элементы списка, можно ли их изменить, присвоив этой переменной другое значение? city
=
"новое значение"
Если мы теперь выведем список lst в консоль:
print
(lst) то окажется, что список не изменился. Почему? Дело в том, что когда мы присваиваем переменной новое значение, то она просто начинает ссылаться на новый объект и на состоянии списка это никак не сказывается.
Вот этот момент работы переменных как ссылок на объекты всегда следует учитывать при программировании на Python. Также следует помнить, что в этом языке типы данных делятся на два класса: изменяемые и неизменяемые. Все предыдущие типы, что мы проходили на прошлых занятиях относились к неизменяемым. Это были: числа, булевые значения, строки
Но вот список list относится к изменяемым типам, то есть, мы можем изменить его состояние, не создавая нового объекта. В самом простом случае мы можем воспользоваться таким синтаксисом: список[индекс] = значение
Например, так: lst[
0
]
=
"Самара"
Теперь первый элемент не «Москва», а «Самара». В действительности, здесь произошло следующее:

Мы поменяли значение ссылки lst[0] первого элемента списка.
Изначально она ссылалась на объект «Москва», а затем, стала ссылаться на объект «Самара». Прежний объект автоматически удаляется сборщиком мусора. Вот так происходит изменение элементов списка, то есть, меняются значения ссылок на новые объекты.
Теперь вернемся к вопросу изменения элементов списка внутри цикла for. Предположим, у нас имеется список чисел: digs
=
[-
1
,
0
,
5
,
3
,
2
] и в цикле мы хотим его изменить на их квадраты. Для этого запишем цикл в таком виде: digs
=
[-
1
,
0
,
5
,
3
,
2
]
for
x
in
range
(
5
): digs[x] **
=
2
#digs[x] = digs[x]**2
print
(digs)
Или, чтобы не указывать конкретное число в функции range, ее можно переписать так:
for
x
in
range
(
len
(digs)):
И программа будет работать со списком произвольной длины.
Во всех наших примерах мы создавали списки небольшой длины и потому могли их запросто записать в программе. Но что если требуется создать список размерностью в 100 или 1000 элементов?
Для этого можно воспользоваться такой конструкцией, например:
A
=
[
0
]*
1000
создает список из 1000 элементов со значением 0. Фактически, мы здесь сначала создали список из одного нулевого элемента, а затем, размножили его до тысячи. Или, можно сделать так:
A
=
[
"none"
]*
100
Получим 100 элементов со строкой «none». И так далее. Кстати, если требуется создать пустой список, то это будет так:
A
=
[]
Ну хорошо, есть у нас список из 100 или 1000 или другого числа элементов. Но как нам теперь с ним работать, например, занести туда какие-либо данные. Для наглядности, предположим, пользователь вводит N чисел с клавиатуры (N<100) и пока он вводит положительные значения, мы их добавляем в список. Как только он ввел какое-либо отрицательное число, считывание прекращается и мы вычисляем среднее арифметическое введенных значений. Это можно реализовать так: digs
=
[
0
]*
100
N
=
0
;
x
=
0
while
x
>=
0
: x
=
int
(
input
(
"Введите целое число: "
)) digs[N]
=
x
N +
=
1
S
=
0
for
x
in
range
(N):
S +
=
digs[x]
S
=
S/N
;
print
(
"S = %f, N = %d"
%(S
,
N))
Теперь, когда мы в целом познакомились со списками, отметим следующие моменты. Список может состоять из произвольных данных, например: t
=
[
"строка"
,
5
,
5.7
,
True
,
[
1
,
2
,
3
]]
Причем, его длина len
(t)
будет равна 5, т.к. последний элемент – вложенный список здесь воспринимается как один отдельный элемент. И этот пример показывает как можно создавать двумерные списки:
A
=
[[
1
,
2
,
3
]
,
[
4
,
5
,
6
]
,
[
7
,
8
,
9
]]
Для доступа к конкретному числу следует сначала обратиться к первому списку:
A[
1
] а, затем, ко второму:
A[
1
][
0
]
Получим значение 4. С этими списками можно выполнять все те же самые операции, о которых мы говорили ранее, например, изменить значение:
A[
1
][
2
]
=
-
1
Далее, списки можно объединять друг с другом, используя оператор +:
[
1
,
2
,
3
] + [
"Москва"
,
"Тверь"
]
Используя этот оператор, можно добавлять новые элементы к списку: digs
=
[
1
,
2
,
3
,
4
] digs
=
digs + [
5
] digs +
=
[
6
] или в начало:
digs
=
[
"числа"
]+digs
И здесь обратите внимание, что мы объединяем именно списки, то есть, вот такая запись: digs
=
digs+
3
приведет к ошибке, т.к. 3 – это число, а не список.
Следующий оператор:
3
in
digs возвращает True, если элемент, записанный слева, присутствует в списке, указанный справа. Иначе, значение False:
-
1
in
digs
Или, можно делать так:
[
1
,
2
,
3
]
in
A
То есть, в качестве элемента может быть любой тип данных.
Следующие две полезные функции: digs
=
[
1
,
2
,
3
,
4
] max
(digs) min
(digs) находят минимальное или максимальное числовое значение. И если в списке имеется не числовой элемент: digs +
=
"a"
то эти функции приводят к ошибкам.
Также можно вычислять сумму элементов числового списка: d
=
[
1
,
2
,
3
,
4
] sum
(d) выполнять сортировку чисел по возрастанию: d
=
[-
1
,
0
,
5
,
3
,
2
,
5
] sorted
(d)
или, по убыванию: sorted
(d
,
reverse
=
True
)
Эта функция возвращает новый объект-список, прежний d остается без изменений.
Наконец, можно сравнивать списки между собой:
[
1
,
2
,
3
]
==
[
1
,
2
,
3
]
[
1
,
2
,
3
]
!=
[
1
,
2
,
3
]
[
1
,
2
,
3
]
>
[
1
,
2
,
3
]
В последнем сравнении получим False, т.к. списки равны, но если записать так:
[
10
,
2
,
3
]
>
[
1
,
2
,
3
] то первый список будет больше второго. Здесь сравнение больше, меньше выполняется по тому же принципу, что и у строк: перебираются последовательно элементы, и если текущий элемент первого списка больше соответствующего элемента второго списка, то первый список больше второго. И аналогично, при сравнении меньше:
[
10
,
2
,
3
]
<
[
1
,
2
,
3
]
Все эти сравнения работают с однотипными данными:
[
1
,
2
,
"abc"
]
>
[
1
,
2
,
"abc"
] сработает корректно, а вот так:
[
1
,
2
,
3
]
>
[
1
,
2
,
"abc"
]
Произойдет ошибка, т.к. число 3 не может быть сравнено со строкой
«abc».
Для списков применим механизм срезов, о котором мы уже говорили, рассматривая строки. Например, пусть у нас имеется список из городов: lst
=
[
"Москва"
,
"Санкт-Петербург"
,
"Тверь"
,
"Казань"
]
Используя синтаксис: список[start:end]
можно выделять элементы, начиная с индекса start и заканчивая, но не включая индекс end. В частности, вот такая конструкция: lst[
1
:
3
] возвратит список из двух городов:
<
p align
=
center
>
[
'Санкт-Петербург'
,
'Тверь'
]
То есть, здесь создается новый объект list, содержащий эти элементы: lst2
=
lst[
2
:
4
]
Прежний список lst не меняется. Если индексы принимают отрицательные значение, то отсчет идет с конца списка: lst[-
2
:-
1
] получим
['Тверь'] так как индекс -1 – последний элемент не включается, остается только
«Тверь». Или, можно записать так: lst[
0
:-
1
] тогда возьмем с первого элемента и до предпоследнего:
['Москва', 'Санкт-Петербург', 'Тверь']
У срезов можно записывать любые числовые индексы к ошибкам это не приведет. Например: lst[
1
:
9999
] вернет список со 2-го элемента и по последний:
['Санкт-Петербург', 'Тверь', 'Казань']
Этот же результат можно получить и так: lst[
1
:] то есть, не указывая последний индекс, берутся все оставшиеся элементы. Если же записать срез так:
lst[:
3
] то элементы выбираются с самого начала и до третьего индекса, то есть, получим:
['Москва', 'Санкт-Петербург', 'Тверь']
Если не указывать ни начало, ни конец, то будет возвращен список: lst[:]
Спрашивается: создает ли данная операция копию списка? Да, создается и в этом легко убедиться, записав такие строчки: c
=
lst[:]
print
(
id
(c)
,
id
(lst))
И мы увидим разные значения id, которые говорят, что обе переменные ссылаются на разные списки. Также копию списка, можно сделать с помощью функции-конструктора list: c
=
list
(lst)
Далее, в срезах можно указывать шаг следования (по умолчанию он равен 1). Для этого пишется еще одно двоеточие и указывается шаг: lst[::
2
] получим:
['Москва', 'Тверь']
Или, такие варианты: lst[
1
:
4
:
2
] lst[:
4
:
3
] lst[
1
::
2
]
Если указать отрицательный шаг, то перебор будет происходить в обратном порядке: lst[::-
1
]
Так как список – это изменяемый объект, то мы можем срезам присваивать новые значения. Делается это таким образом: lst[
1
:
3
]
=
"Владимир"
,
"Астрахань"

В результате, получаем список:
['Москва', 'Владимир', 'Астрахань', 'Казань']
Или даже так. Большему срезу присвоить меньшее число элементов: lst[
0
:
3
]
=
'Пермь'
,
'Пенза'
В итоге получаем список:
['Пермь', 'Пенза', 'Казань']
Однако, если нам нужно просто удалить какой-либо элемент, то это делается с помощью оператора del:
del
lst[
1
]
В результате будет удален элемент с индексом 1 из списка lst:
['Пермь', 'Казань']
Методы списков
Давайте теперь предположим, что у нас имеется список из чисел: a
=
[
1
,
-
54
,
3
,
23
,
43
,
-
45
,
0
] и мы хотим в конец этого списка добавить значение. Это можно сделать с помощью метода: a.append(
100
)

И обратите внимание: метод append ничего не возвращает, то есть, он меняет сам список благодаря тому, что он относится к изменяемому типу данных. Поэтому писать здесь конструкцию типа a
=
a.append(
100
) категорически не следует, так мы только потеряем весь наш список! И этим методы списков отличаются от методов строк, когда мы записывали: string
=
"Hello"
string
=
string
.upper()
Здесь метод upper возвращает измененную строку, поэтому все работает как и ожидается. А метод append ничего не возвращает, и присваивать значение None переменной a не имеет смысла, тем более, что все работает и так: a
=
[
1
,
-
54
,
3
,
23
,
43
,
-
45
,
0
] a.append(
100
)
Причем, мы в методе append можем записать не только число, но и другой тип данных, например, строку: a.append(
"hello"
) тогда в конец списка будет добавлен этот элемент. Или, булевое значение: a.append(
True
)
Или еще один список: a.append([
1
,
2
,
3
])
И так далее. Главное, чтобы было указано одно конкретное значение.
Вот так работать не будет: a.append(
1
,
2
)
Если нам нужно вставить элемент в произвольную позицию, то используется метод a.insert(
3
,
-
1000
)
Здесь мы указываем индекс вставляемого элемента и далее значение самого элемента.

Следующий метод remove удаляет элемент по значению: a.remove(
True
) a.remove(
'hello'
)
Он находит первый подходящий элемент и удаляет его, остальные не трогает. Если же указывается несуществующий элемент: a.remove(
'hello2'
) то возникает ошибка. Еще один метод для удаления a.pop() выполняет удаление последнего элемента и при этом, возвращает его значение. В самом списке последний элемент пропадает. То есть, с помощью этого метода можно сохранять удаленный элемент в какой- либо переменной: end
=
a.pop()
Также в этом методе можно указывать индекс удаляемого элемента, например: a.pop(
3
)
Если нам нужно очистить весь список – удалить все элементы, то можно воспользоваться методом: a.clear()
Получим пустой список. Следующий метод a
=
[
1
,
-
54
,
3
,
23
,
43
,
-
45
,
0
] c
=
a.
copy
() возвращает копию списка. Это эквивалентно конструкции: c
=
list
(a)
В этом можно убедиться так: c[
1
]
=
1
и список c будет отличаться от списка a.

Следующий метод count позволяет найти число элементов с указанным значением: c.count(
1
) c.count(-
45
)
Если же нам нужен индекс определенного значения, то для этого используется метод index: c.index(-
45
) c.index(
1
) возвратит 0, т.к. берется индекс только первого найденного элемента.
Но, мы здесь можем указать стартовое значение для поиска: c.index(
1
,
1
)
Здесь поиск будет начинаться с индекса 1, то есть, со второго элемента. Или, так: c.index(
23
,
1
,
5
)
Ищем число 23 с 1-го индекса и по 5-й не включая его. Если элемент не находится c.index(
23
,
1
,
3
) то метод приводит к ошибке. Чтобы этого избежать в своих программах, можно вначале проверить: существует ли такой элемент в нашем срезе:
23
in
c[
1
:
3
] и при значении True далее уже определять индекс этого элемента.
Следующий метод c.reverse() меняет порядок следования элементов на обратный.
Последний метод, который мы рассмотрим, это c.sort() выполняет сортировку элементов списка по возрастанию. Для сортировки по убыванию, следует этот метод записать так:
c.sort(reverse
=
True
)
Причем, этот метод работает и со строками: lst
=
[
"Москва"
,
"Санкт-Петербург"
,
"Тверь"
,
"Казань"
] lst.sort()
Здесь используется лексикографическое сравнение, о котором мы говорили, когда рассматривали строки.
Это все основные методы списков и чтобы вам было проще ориентироваться, приведу следующую таблицу:
Метод
Описание append()
Добавляет элемент в конец списка insert()
Вставляет элемент в указанное место списка remove()
Удаляет элемент по значению pop()
Удаляет последний элемент, либо элемент с указанным индексом clear()
Очищает список (удаляет все элементы) copy()
Возвращает копию списка count()
Возвращает число элементов с указанным значением index()
Возвращает индекс первого найденного элемента reverse()
Меняет порядок следования элементов на обратный sort()
Сортирует элементы списка
Вот мы с вами и подошли к одному из фундаментальных моментов в изучении языка Python – функциям. Что это такое? Смотрите.
Например, уже знакомая вам функция print() выводит сообщения в консоль. Фактически же при ее вызове выполняется определенный фрагмент программы, результатом которого и является вывод информации в заданном виде. И это очень удобно. Благодаря наличию таких функций нам не нужно каждый раз писать дублирующие инструкции для выполнения типовых операций.
Собственно, это главное предназначение функций – многократное выполнение определенного фрагмента программы.

Язык Python позволяет программисту создавать свои собственные функции. Для этого используется следующий синтаксис: def <имя функции>([список аргументов]): оператор 1 оператор 2
… оператор N
Здесь имя функции придумывается программистом подобно именам переменных и, так как функция – это определенное действие, то ее имя следует выбирать как глагол, например: go, show, get, set и т.п.
Далее, идет набор операторов, которые образуют тело функции.
Именно они начинают выполнятся при ее вызове.
Давайте зададим простейшую функцию, которая будет выводить
«hello» в консоль:
def
sayHello():
print
(
"hello"
)
Смотрите, мы здесь придумали имя функции «sayHello», записали пустые круглые скобки без аргументов и через двоеточие определили тело функции в виде конструкции print("hello"). Но это лишь определение функции. Самого вызова здесь еще нет и если запустить программу, то ничего не произойдет.
Чтобы вызвать эту функцию, нужно указать ее имя и в конце обязательно поставить круглые скобки даже если мы не передаем ей никаких аргументов: sayHello()
Эти круглые скобки являются оператором вызова функции с указанным именем. Теперь, при запуске программы в консоли появится сообщение «hello».
Имя функции без круглых скобок – это фактически ссылка на функцию:
print
( type
(sayHello) ) то есть, ссылка на специальный объект, представляющий ту или иную функцию. А раз это ссылка, то мы можем выполнить такую операцию:
f
=
sayHello тем самым определить ее синоним и вызвать ее уже через это второе имя: f()
Как мы говорили в самом начале, функции, как правило, создаются для их многократного вызова. И действительно, мы теперь, можем ее вызывать в любом месте нашей программы необходимое число раз, например, так: sayHello()
1   2   3   4   5


написать администратору сайта