Книга Изучаем Python
Скачать 4.68 Mb.
|
54 Глава 3 • Списки popped_motorcycle . Вывод измененного списка в точке показывает, что значе- ние было удалено из списка. Затем мы выводим извлеченное значение в точке , демонстрируя, что удаленное из списка значение остается доступным в программе. Из вывода видно, что значение 'suzuki' , удаленное в конце списка, теперь хранится в переменной popped_motorcycle : ['honda', 'yamaha', 'suzuki'] ['honda', 'yamaha'] suzuki Для чего может понадобиться метод pop() ? Представьте, что мотоциклы в списке хранятся в хронологическом порядке в соответствии с датой их покупки. В таком случае команда pop() может использоваться для вывода сообщения о последнем купленном мотоцикле: motorcycles = ['honda', 'yamaha', 'suzuki'] last_owned = motorcycles.pop() print("The last motorcycle I owned was a " + last_owned.title() + ".") Программа выводит простое сообщение: The last motorcycle I owned was a Suzuki. Извлечение элементов из произвольной позиции списка Вызов pop() может использоваться для удаления элемента в произвольной позиции списка; для этого следует указать индекс удаляемого элемента в круглых скобках. motorcycles = ['honda', 'yamaha', 'suzuki'] first_owned = motorcycles.pop(0) print('The first motorcycle I owned was a ' + first_owned.title() + '.') Сначала первый элемент извлекается из списка в точке , а затем в точке вы- водится сообщение об этом мотоцикле. Программа выводит простое сообщение о первом мотоцикле: The first motorcycle I owned was a Honda. Помните, что после каждого вызова pop() элемент, с которым вы работаете, уже не находится в списке. Если вы не уверены в том, какой из двух способов выбрать — команду del или ме- тод pop() , — то простое правило поможет вам определиться. Если вы собираетесь просто удалить элемент из списка, никак не используя его, выбирайте команду del ; если же вы намерены использовать элемент после удаления из списка, выбирайте метод pop() Удаление элементов по значению Иногда позиция удаляемого элемента неизвестна. Если вы знаете только значение элемента, используйте метод remove() Индексы начинаются с 0, а не с 1 55 Допустим, из списка нужно удалить значение ' ducati' : motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati'] print(motorcycles) motorcycles.remove('ducati') print(motorcycles) Код в точке приказывает Python определить, в какой позиции списка находится значение 'ducati' , и удалить этот элемент: ['honda', 'yamaha', 'suzuki', 'ducati'] ['honda', 'yamaha', 'suzuki'] Метод remove() также может использоваться для работы со значением, которое удаляется из списка. Следующая программа удаляет значение 'ducati' и выводит причину удаления: motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati'] print(motorcycles) too_expensive = 'ducati' motorcycles.remove(too_expensive) print(motorcycles) print("\nA " + too_expensive.title() + " is too expensive for me.") После определения списка в точке значение 'ducati' сохраняется в перемен- ной с именем too_expensive в точке . Затем эта переменная сообщает Python, какое значение должно быть удалено из списка . В точке значение 'ducati' было удалено из списка, но продолжает храниться в переменной too_expensive , что позволяет вывести сообщение с причиной удаления 'ducati' из списка мо- тоциклов: ['honda', 'yamaha', 'suzuki', 'ducati'] ['honda', 'yamaha', 'suzuki'] A Ducati is too expensive for me. ПРИМЕЧАНИЕ Метод remove() удаляет только первое вхождение заданного значения . Если существует вероят- ность того, что значение встречается в списке более одного раза, используйте цикл для опреде- ления того, были ли удалены все вхождения данного значения . О том, как это делать, рассказано в главе 7 . УПРАЖНЕНИЯ Следующие упражнения немного сложнее упражнений из главы 2, но они предоставляют возможность попрактиковаться в выполнении всех описанных операций со списками . 3-4 . Список гостей: если бы вы могли пригласить кого угодно (из живых или умерших) на обед, то кого бы вы пригласили? Создайте список, включающий минимум трех людей, которых вам хотелось бы пригласить на обед . Затем используйте этот список для вывода пригласительного сообщения каждому участнику . 56 Глава 3 • Списки 3-5 . Изменение списка гостей: вы только что узнали, что один из гостей прийти не сможет, поэтому вам придется разослать новые приглашения . Отсутствующего гостя нужно заме- нить кем-то другим . • Начните с программы из упражнения 3-4 . Добавьте в конец программы команду print для вывода имени гостя, который прийти не сможет . • Измените список и замените имя гостя, который прийти не сможет, именем нового приглашенного . • Выведите новый набор сообщений с приглашениями – по одному для каждого участ- ника, входящего в список . 3-6 . Больше гостей: вы решили купить обеденный стол большего размера . Дополнительные места позволяют пригласить на обед еще трех гостей . • Начните с программы из упражнения 3-4 или 3-5 . Добавьте в конец программы коман- ду print, которая выводит сообщение о расширении списка гостей . • Добавьте вызов insert() для добавления одного гостя в начало списка . • Добавьте вызов insert() для добавления одного гостя в середину списка . • Добавьте вызов append() для добавления одного гостя в конец списка . • Выведите новый набор сообщений с приглашениями – по одному для каждого участ- ника, входящего в список . 3-7 . Сокращение списка гостей: только что выяснилось, что новый обеденный стол привез- ти вовремя не успеют, и места хватит только для двух гостей . • Начните с программы из упражнения 3-6 . Добавьте команду для вывода сообщения о том, что на обед приглашаются всего два гостя . • Используйте метод pop() для последовательного удаления гостей из списка до тех пор, пока в списке не останутся только два человека . Каждый раз, когда из списка удаляется очередное имя, выведите для этого человека сообщение о том, что вы со- жалеете об отмене приглашения . • Выведите сообщение для каждого из двух человек, остающихся в списке . Сообщение должно подтверждать, что более раннее приглашение остается в силе . • Используйте команду del для удаления двух последних имен, чтобы список остался пустым . Выведите список, чтобы убедиться в том, что в конце работы программы список действительно не содержит ни одного элемента . Упорядочение списка Нередко список создается в непредсказуемом порядке, потому что порядок полу- чения данных от пользователя не всегда находится под вашим контролем. И хотя во многих случаях такое положение дел неизбежно, часто требуется вывести информацию в определенном порядке. В одних случаях требуется сохранить исходный порядок элементов в списке, в других исходный порядок должен быть изменен. Python предоставляет в распоряжение программиста несколько разных способов упорядочения списка в зависимости от ситуации. Постоянная сортировка списка методом sort() Метод sort() позволяет относительно легко отсортировать список. Предположим, имеется список машин, и вы хотите переупорядочить эти элементы по алфавиту. Упорядочение списка 57 Чтобы упростить задачу, предположим, что все значения в списке состоят из сим- волов нижнего регистра. cars.py cars = ['bmw', 'audi', 'toyota', 'subaru'] cars.sort() print(cars) Метод sort() в точке осуществляет постоянное изменение порядка элементов в списке. Названия машин располагаются в алфавитном порядке, и вернуться к ис- ходному порядку уже не удастся: ['audi', 'bmw', 'subaru', 'toyota'] Список также можно отсортировать в обратном алфавитном порядке; для этого методу sort() следует передать аргумент reverse=True . В следующем примере список сортируется в порядке, обратном алфавитному: cars = ['bmw', 'audi', 'toyota', 'subaru'] cars.sort(reverse=True) print(cars) И снова порядок элементов изменяется на постоянной основе: ['toyota', 'subaru', 'bmw', 'audi'] Временная сортировка списка функцией sorted() Чтобы сохранить исходный порядок элементов списка, но временно представить их в отсортированном порядке, можно воспользоваться функцией sorted() . Функция sorted() позволяет представить список в определенном порядке, но не изменяет фактического порядка элементов в списке. Попробуем применить эту функцию к списку машин. cars = ['bmw', 'audi', 'toyota', 'subaru'] print("Here is the original list:") print(cars) print("\nHere is the sorted list:") print(sorted(cars)) print("\nHere is the original list again:") print(cars) Сначала список выводится в исходном порядке , а затем в алфавитном . После того как список будет выведен в новом порядке, в точке , мы убеждаемся в том, что список все еще хранится в исходном порядке. Here is the original list: ['bmw', 'audi', 'toyota', 'subaru'] Here is the sorted list: 58 Глава 3 • Списки ['audi', 'bmw', 'subaru', 'toyota'] Here is the original list again: ['bmw', 'audi', 'toyota', 'subaru'] Обратите внимание: после вызова функции sorted() список продолжает хранить- ся в исходном порядке . Функции sorted() также можно передать аргумент reverse=True , чтобы список был представлен в порядке, обратном алфавитному. ПРИМЕЧАНИЕ Если не все значения записаны в нижнем регистре, алфавитная сортировка списка немного услож- няется . При определении порядка сортировки появляются разные способы интерпретации пропис- ных букв, и точное определение порядка уже не столь важно (во всяком случае, чтобы отвлекаться на него сейчас) . Впрочем, большинство способов сортировки напрямую следует из того, о чем вы узнали в этом разделе . Вывод списка в обратном порядке Чтобы переставить элементы списка в обратном порядке, используйте метод reverse() . Скажем, если список машин первоначально хранился в хронологиче- ском порядке даты приобретения, элементы можно легко переупорядочить в об- ратном хронологическом порядке: cars = ['bmw', 'audi', 'toyota', 'subaru'] print(cars) cars.reverse() print(cars) Обратите внимание: метод reverse() не сортирует элементы в обратном алфавит- ном порядке, а просто переходит к обратному порядку списка: ['bmw', 'audi', 'toyota', 'subaru'] ['subaru', 'toyota', 'audi', 'bmw'] Метод reverse() осуществляет постоянное изменение порядка элементов, но вы можете легко вернуться к исходному порядку, снова применив reverse() к об- ратному списку. Определение длины списка Вы можете быстро определить длину списка с помощью функции len() . Список в нашем примере состоит из четырех элементов, поэтому его длина равна 4: >>> cars = ['bmw', 'audi', 'toyota', 'subaru'] >>> len(cars) 4 Метод len() может пригодиться для определения количества пришельцев, кото- рых необходимо сбить в игре; объема данных, которыми необходимо управлять в визуализации; количества зарегистрированных пользователей на веб-сайте и т. д. Ошибки индексирования при работе со списками 59 ПРИМЕЧАНИЕ Python подсчитывает элементы списка, начиная с 1, поэтому при определении длины списка оши- бок «смещения на 1» уже быть не должно . УПРАЖНЕНИЯ 3-8 . Повидать мир: вспомните хотя бы пять стран, в которых вам хотелось бы побывать . • Сохраните названия стран в списке . Проследите за тем, чтобы список не хранился в алфавитном порядке . • Выведите список в исходном порядке . Не беспокойтесь об оформлении списка, просто выведите его как обычный список Python . • Используйте функцию sorted() для вывода списка в алфавитном порядке без измене- ния списка . • Снова выведите список, чтобы показать, что он по-прежнему хранится в исходном порядке . • Используйте функцию sorted() для вывода списка в обратном алфавитном порядке без изменения порядка исходного списка . • Снова выведите список, чтобы показать, что исходный порядок не изменился . • Измените порядок элементов вызовом reverse() . Выведите список, чтобы показать, что элементы следуют в другом порядке . • Измените порядок элементов повторным вызовом reverse() . Выведите список, чтобы показать, что список вернулся к исходному порядку . • Отсортируйте список в алфавитном порядке вызовом sort() . Выведите список, чтобы показать, что элементы следуют в другом порядке . • Вызовите sort() для перестановки элементов списка в обратном алфавитном порядке . Выведите список, чтобы показать, что порядок элементов изменился . 3-9 . Количество гостей: в одной из программ из упражнений с 3-4 по 3-7 используйте len() для вывода сообщения с количеством людей, приглашенных на обед . 3-10 . Все функции: придумайте информацию, которую можно было бы хранить в списке . Например, создайте список гор, рек, стран, городов, языков… словом, чего угодно . Напи- шите программу, которая создает список элементов, а затем вызывает каждую функцию, упоминавшуюся в этой главе, хотя бы один раз . Ошибки индексирования при работе со списками Когда программист только начинает работать со списками, он часто допускает одну характерную ошибку. Допустим, имеется список с тремя элементами, и программа запрашивает четвертый элемент: motorcycles = ['honda', 'yamaha', 'suzuki'] print(motorcycles[3]) В этом случае происходит ошибка индексирования: Traceback (most recent call last): File "motorcycles.py", line 3, in print(motorcycles[3]) IndexError: list index out of range 60 Глава 3 • Списки Python пытается вернуть элемент с индексом 3. Однако при поиске по списку ни один элемент motorcycles не обладает индексом 3. Из-за смещения индексов на 1 эта ошибка весьма распространена. Люди думают, что третьим элементом является элемент с индексом 3, потому что они начинают отсчет с 1. Но для Python третьим является элемент с индексом 2, потому что индексирование начинается с 0. Ошибка индексирования означает, что Python не может понять, какой индекс за- прашивается в программе. Если в вашей программе происходит ошибка индексиро- вания, попробуйте уменьшить запрашиваемый индекс на 1. Затем снова запустите программу и проверьте правильность результатов. Помните, что для обращения к последнему элементу в списке используется индекс –1. Этот способ работает всегда, даже если размер списка изменился с момента последнего обращения к нему: motorcycles = ['honda', 'yamaha', 'suzuki'] print(motorcycles[-1]) Индекс –1 всегда возвращает последний элемент списка, в данном случае значение 'suzuki' : 'suzuki' Этот синтаксис порождает ошибку только в одном случае — при попытке получить последний элемент пустого списка: motorcycles = [] print(motorcycles[-1]) В списке motorcycles нет ни одного элемента, поэтому Python снова выдает ошибку индексирования: Traceback (most recent call last): File "motorcyles.py", line 3, in IndexError: list index out of range ПРИМЕЧАНИЕ Если в вашей программе произошла ошибка индексирования и вы не знаете, как с ней справиться, попробуйте вывести список или хотя бы его длину . Возможно, ваш список выглядит совсем не так, как вы думаете, особенно если его содержимое динамически определялось программой . Фактиче- ское состояние списка или точное количество элементов в нем поможет вам выявить логические ошибки такого рода . УПРАЖНЕНИЯ 3-11 . Намеренная ошибка: если ни в одной из предшествующих программ вы еще не стал- кивались с ошибками индексирования, попробуйте создать такую ошибку искусственно . Измените индекс в одной из программ, чтобы вызвать ошибку индексирования . Не забудьте исправить ошибку перед тем, как закрыть программу . Итоги 61 Итоги В этой главе вы узнали, что представляют собой списки и как работать с отдельны- ми элементами в списках. Вы научились определять списки, добавлять и удалять элементы, выполнять сортировку (постоянную или временную для отображения). Также вы узнали, как определить длину списка и как избежать ошибок индекси- рования при работе со списком. В главе 4 рассматриваются приемы более эффективной работы со списками. Пере- бор всех элементов списка всего в нескольких строках кода, даже если список со- держит тысячи или миллионы элементов, сокращает объем программы. 4 Работа со списками В главе 3 вы научились создавать простые списки и работать с отдельными элемен- тами списков. В этой главе вы узнаете, как перебрать весь список всего в несколь- ких строках кода (независимо от длины списка). Механизм перебора позволяет выполнить одно действие или набор действий с каждым элементом в списке. С его помощью вы сможете эффективно работать со списками любой длины, даже со- стоящими из тысяч и миллионов элементов. Перебор всего списка Типичная задача из области программирования — перебрать все элементы списка и выполнить с каждым элементом одну и ту же операцию. Например, в компью- терной игре все экранные объекты могут смещаться на одинаковую величину, или в списке чисел к каждому элементу может применяться одна и та же стати- стическая операция. А может быть, вам нужно вывести все заголовки из списка статей на сайте. В ситуациях, требующих применения одного действия к каждому элементу списка, можно воспользоваться циклами for Допустим, имеется список с именами фокусников, и вы хотите вывести каждое имя из списка. Конечно, можно обратиться к каждому элементу по отдельности, но такой подход создает ряд проблем. Во-первых, для очень длинных списков все сведется к однообразным повторениям. Во-вторых, при любом изменении длины списка в программу придется вносить изменения. Цикл for решает обе проблемы: Python будет следить за всеми техническими деталями в своей внутренней реали- зации. В следующем примере цикл for используется для вывода имен фокусников: magicians.py magicians = ['alice', 'david', 'carolina'] for magician in magicians: print(magician) Все начинается с определения списка , как и в главе 3. В точке определяется цикл for . Эта строка приказывает Python взять очередное имя из списка и сохра- нить его в переменной magician . В точке выводится имя, только что сохранен- ное в переменной magician . Затем строки и повторяются для каждого имени |