Главная страница
Навигация по странице:

  • УПРАЖНЕНИЯ 4-10 . Срезы: добавьте в конец одной из программ, написанных в этой главе, фрагмент, который делает следующее . Кортежи 77

  • Книга Изучаем Python


    Скачать 4.68 Mb.
    НазваниеКнига Изучаем Python
    Дата10.12.2022
    Размер4.68 Mb.
    Формат файлаpdf
    Имя файлаErik_Metiz_Izuchaem_Python_Programmirovanie_igr_vizualizatsia_da.pdf
    ТипКнига
    #837531
    страница9 из 53
    1   ...   5   6   7   8   9   10   11   12   ...   53
    digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    >>> min(digits)
    0
    >>> max(digits)
    9
    >>> sum(digits)
    45
    ПРИМЕЧАНИЕ
    В примерах этой главы используются короткие списки чисел, но это делается только для того, что- бы данные помещались на странице . Примеры также будут работать и в том случае, если список содержит миллионы чисел .
    Генераторы списков
    Описанный выше способ генерирования списка squares состоял из трех или четырех строк кода. Генератор списка (list comprehension) позволяет сгенериро-

    72 Глава 4 • Работа со списками вать тот же список всего в одной строке. Генератор списка объединяет цикл for и создание новых элементов в одну строку и автоматически присоединяет к списку все новые элементы. Учебники не всегда рассказывают о генераторах списка на- чинающим программистам, но я привожу этот материал, потому что вы с большой вероятностью встретите эту конструкцию, как только начнете просматривать код других разработчиков.
    В следующем примере список квадратов, знакомый вам по предыдущим примерам, строится с использованием генератора списка:
    squares.py
    squares = [value**2 for value in range(1,11)]
    print(squares)
    Чтобы использовать этот синтаксис, начните с содержательного имени списка, например squares
    . Затем откройте квадратные скобки и определите выражение для значений, которые должны быть сохранены в новом списке. В данном приме- ре это выражение value**2
    , которое возводит значение во вторую степень. Затем напишите цикл for для генерирования чисел, которые должны передаваться вы- ражению, и закройте квадратные скобки. Цикл for в данном примере — for value in range(1,11)
    — передает значения с 1 до 10 выражению value**2
    . Обратите внимание на отсутствие двоеточия в конце команды for
    Результатом будет уже знакомый вам список квадратов:
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    Чтобы успешно писать собственные генераторы списков, необходим определенный опыт. Тем не менее, как только вы освоитесь с созданием обычных списков, вы оцените возможности генераторов. Когда после очередного трех-четырехстрочного блока вам это надоест, подумайте о написании собственных генераторов списков.
    УПРАЖНЕНИЯ
    4-3 . Считаем до 20: используйте цикл for для вывода чисел от 1 до 20 включительно .
    4-4 . Миллион: создайте список чисел от 1 до 1 000 000, затем воспользуйтесь циклом for для вывода чисел . (Если вывод занимает слишком много времени, остановите его нажатием
    Ctrl+C или закройте окно вывода .)
    4-5 . Суммирование миллиона чисел: создайте список чисел от 1 до 1 000 000, затем вос- пользуйтесь функциями min() и max() и убедитесь в том, что список действительно начи- нается с 1 и заканчивается 1 000 000 . Вызовите функцию sum() и посмотрите, насколько быстро Python сможет просуммировать миллион чисел .
    4-6 . Нечетные числа: воспользуйтесь третьим аргументом функции range() для создания списка нечетных чисел от 1 до 20 . Выведите все числа в цикле for .
    4-7 . Тройки: создайте список чисел, кратных 3, в диапазоне от 3 до 30 . Выведите все числа своего списка в цикле for .
    4-8 . Кубы: результат возведения числа в третью степень называется кубом . Например, куб 2 записывается в языке Python в виде 2**3 . Создайте список первых 10 кубов (то есть кубов всех целых чисел от 1 до 10) и выведите значения всех кубов в цикле for .
    4-9 . Генератор кубов: используйте конструкцию генератора списка для создания списка первых 10 кубов .

    Работа с частью списка 73
    Работа с частью списка
    В главе 3 вы узнали, как обращаться к отдельным элементам списка, а в этой главе мы занимались перебором всех элементов списка. Также можно работать с конкрет- ным подмножеством элементов списка; в Python такие подмножества называются
    срезами (slices).
    Создание среза
    Чтобы создать срез списка, следует задать индексы первого и последнего элементов, с которыми вы намереваетесь работать. Как и в случае с функцией range()
    , Python останавливается на элементе, предшествующем второму индексу. Скажем, чтобы вывести первые три элемента списка, запросите индексы с 0 по 3, и вы получите элементы 0, 1 и 2.
    В следующем примере используется список игроков команды:
    players.py
    players = ['charles', 'martina', 'michael', 'florence', 'eli']
     print(players[0:3])
    В точке  выводится срез списка, включающий только первых трех игроков. Вывод сохраняет структуру списка, но включает только первых трех игроков:
    ['charles', 'martina', 'michael']
    Подмножество может включать любую часть списка. Например, чтобы ограничить- ся вторым, третьим и четвертым элементами списка, срез начинается с индекса 1 и заканчивается на индексе 4:
    players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[1:4])
    На этот раз срез начинается с элемента 'martina'
    и заканчивается элементом 'florence'
    :
    ['martina', 'michael', 'florence']
    Если первый индекс среза не указан, то Python автоматически начинает срез от начала списка:
    players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[:4])
    Без начального индекса Python берет элементы от начала списка:
    ['charles', 'martina', 'michael', 'florence']
    Аналогичный синтаксис работает и для срезов, включающих конец списка. Напри- мер, если вам нужны все элементы с третьего до последнего, начните с индекса 2 и не указывайте второй индекс:
    players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[2:])

    74 Глава 4 • Работа со списками
    Python возвращает все элементы с третьего до конца списка:
    ['michael', 'florence', 'eli']
    Этот синтаксис позволяет вывести все элементы от любой позиции до конца спи- ска независимо от его длины. Вспомните, что отрицательный индекс возвращает элемент, находящийся на заданном расстоянии от конца списка; следовательно, вы можете получить любой срез от конца списка. Например, чтобы отобрать последних трех игроков, используйте срез players[-3:]
    :
    players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[-3:])
    Программа выводит имена трех последних игроков, причем продолжает работать даже при изменении размера списка.
    Перебор содержимого среза
    Если вы хотите перебрать элементы, входящие в подмножество элементов, исполь- зуйте срез в цикле for
    . В следующем примере программа перебирает первых трех игроков и выводит их имена:
    players = ['charles', 'martina', 'michael', 'florence', 'eli']
    print("Here are the first three players on my team:")
     for player in players[:3]:
    print(player.title())
    Вместо того чтобы перебирать весь список игроков , Python ограничивается первыми тремя именами:
    Here are the first three players on my team:
    Charles
    Martina
    Michael
    Срезы приносят огромную пользу во многих ситуациях. Например, при создании компьютерной игры итоговый счет игрока может добавляться в список после окончания текущей партии. После этого программа может получить три лучших ре- зультата игрока, отсортировав список по уменьшению и получив срез, включающий только три элемента. При работе с данными срезы могут использоваться для об- работки данных блоками заданного размера. Или при построении веб-приложения срезы могут использоваться для постраничного вывода информации так, чтобы на каждой странице выводился соответствующий объем информации.
    Копирование списка
    Часто разработчик берет существующий список и создает на его основе совершенно новый. Посмотрим, как работает копирование списков, и рассмотрим одну ситуа- цию, в которой копирование списка может принести пользу.

    Работа с частью списка 75
    Чтобы скопировать список, создайте срез, включающий весь исходный список без указания первого и второго индекса (
    [:]
    ). Эта конструкция создает срез, который начинается с первого элемента и завершается последним; в результате создается копия всего списка.
    Представьте, что вы создали список своих любимых блюд и теперь хотите создать отдельный список блюд, которые нравятся вашему другу. Пока вашему другу нравятся все блюда из нашего списка, поэтому вы можете создать другой список простым копированием нашего:
    foods.py
     my_foods = ['pizza', 'falafel', 'carrot cake']
     friend_foods = my_foods[:]
    print("My favorite foods are:")
    print(my_foods)
    print("\nMy friend's favorite foods are:")
    print(friend_foods)
    В точке  создается список блюд с именем my_foods
    . В точке  создается дру- гой список с именем friend_foods
    . Чтобы создать копию my_foods
    , программа запрашивает срез my_foods без указания индексов, и мы сохраняем копию в friend_foods
    При выводе обоих списков становится видно, что они содержат одинаковые данные:
    My favorite foods are:
    ['pizza', 'falafel', 'carrot cake']
    My friend's favorite foods are:
    ['pizza', 'falafel', 'carrot cake']
    Чтобы доказать, что речь в действительности идет о двух разных списках, добавим новое блюдо в каждый список:
    my_foods = ['pizza', 'falafel', 'carrot cake']
     friend_foods = my_foods[:]
     my_foods.append('cannoli')
     friend_foods.append('ice cream')
    print("My favorite foods are:")
    print(my_foods)
    print("\nMy friend's favorite foods are:")
    print(friend_foods)
    В точке  исходные элементы my_foods копируются в новый список friend_foods
    , как было сделано в предыдущем примере. Затем в  каждый список добавляется новый элемент:
    'cannoli'
    в my_foods
    , и 'ice cream'
    в friend_foods
    . После этого вывод двух списков наглядно показывает, что каждое блюдо находится в соответ- ствующем списке.

    76 Глава 4 • Работа со списками
    My favorite foods are:

    ['pizza', 'falafel', 'carrot cake', 'cannoli']
    My friend's favorite foods are:

    ['pizza', 'falafel', 'carrot cake', 'ice cream']
    Вывод в точке  показывает, что элемент 'cannoli'
    находится в списке my_foods
    , а элемент 'ice cream'
    в этот список не входит. В точке  видно, что 'ice cream'
    входит в список friend_foods
    , а элемент 'cannoli'
    в этот список не входит. Если бы эти два списка просто совпадали, то их содержимое уже не различалось бы.
    Например, вот что происходит при попытке копирования списка без использо- вания среза:
    my_foods = ['pizza', 'falafel', 'carrot cake']
    # This doesn't work:
     friend_foods = my_foods my_foods.append('cannoli')
    friend_foods.append('ice cream')
    print("My favorite foods are:")
    print(my_foods)
    print("\nMy friend's favorite foods are:")
    print(friend_foods)
    Вместо того чтобы сохранять копию my_foods в friend_foods в точке , мы зада- ем friend_foods равным my_foods
    . Этот синтаксис в действительности сообщает
    Python, что новая переменная friend_foods должна быть связана со списком, уже хранящимся в my_foods
    , поэтому теперь обе переменные связаны с одним списком.
    В результате при добавлении элемента 'cannoli'
    в my_foods этот элемент также появляется в friend_foods
    . Аналогичным образом элемент 'ice cream'
    появляется в обоих списках, хотя на первый взгляд он был добавлен только в friend_foods
    Вывод показывает, что оба списка содержат одинаковые элементы, а это совсем не то, что требовалось:
    My favorite foods are:
    ['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
    My friend's favorite foods are:
    ['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
    ПРИМЕЧАНИЕ
    Если какие-то подробности в этом примере кажутся непонятными, не огорчайтесь . В двух словах, если при работе с копией списка происходит что-то непредвиденное, убедитесь в том, что список копируется с использованием среза, как это делается в нашем первом примере .
    УПРАЖНЕНИЯ
    4-10 . Срезы: добавьте в конец одной из программ, написанных в этой главе, фрагмент, который делает следующее .

    Кортежи 77
    • Выводит сообщение «The first three items in the list are:», а затем использует срез для вывода первых трех элементов из списка .
    • Выводит сообщение «Three items from the middle of the list are:», а затем использует срез для вывода первых трех элементов из середины списка .
    • Выводит сообщение «The last three items in the list are:», а затем использует срез для вывода последних трех элементов из списка .
    4-11 . Моя пицца, твоя пицца: начните с программы из упражнения 4-1 . Создайте копию списка с видами пиццы, присвойте ему имя friend_pizzas . Затем сделайте следующее .
    • Добавьте новую пиццу в исходный список .
    • Добавьте другую пиццу в список friend_pizzas .
    • Докажите, что в программе существуют два разных списка . Выведите сообщение «My favorite pizzas are:», а затем первый список в цикле for . Выведите сообщение «My friend’s favorite pizzas are:», а затем второй список в цикле for . Убедитесь в том, что каждая новая пицца находится в соответствующем списке .
    4-12 . Больше циклов: во всех версиях foods .py из этого раздела мы избегали использования цикла for при выводе для экономии места . Выберите версию foods .py и напишите два цикла for для вывода каждого списка .
    Кортежи
    Списки хорошо подходят для хранения наборов элементов, которые могут из- меняться на протяжении жизненного цикла программы. Например, возможность модификации списков жизненно необходима при работе со списками пользовате- лей сайта или списками персонажей игры. Однако в некоторых ситуациях требу- ется создать список элементов, который не может изменяться. Кортежи (tuples) предоставляют именно такую возможность. В языке Python значения, которые не могут изменяться, называются неизменяемыми (immutable), а неизменяемый список называется кортежем.
    Определение кортежа
    Кортеж выглядит как список, не считая того, что вместо квадратных скобок исполь- зуются круглые скобки. После определения кортежа вы можете обращаться к его от- дельным элементам по индексам точно так же, как это делается при работе со списком.
    Допустим, имеется прямоугольник, который в программе всегда должен иметь строго определенные размеры. Чтобы гарантировать неизменность размеров, мож- но объединить размеры в кортеж:
    dimensions.py
     dimensions = (200, 50)
     print(dimensions[0])
    print(dimensions[1])
    В точке  определяется кортеж dimensions
    , при этом вместо квадратных скобок используются круглые. В точке  каждый элемент кортежа выводится по отдельно- сти с использованием того же синтаксиса, который использовался для обращения к элементу списка:

    78 Глава 4 • Работа со списками
    200 50
    Посмотрим, что произойдет при попытке изменения одного из элементов в кортеже dimensions
    :
    dimensions = (200, 50)
     dimensions[0] = 250
    Код в точке  пытается изменить первое значение, но Python возвращает ошибку типа. По сути, так как мы пытаемся изменить кортеж, а эта операция недопустима для объектов этого типа, Python сообщает о невозможности присваивания нового значения элементу в кортеже:
    Traceback (most recent call last):
    File "dimensions.py", line 3, in
    dimensions[0] = 250
    TypeError: 'tuple' object does not support item assignment
    И это хорошо, потому что мы хотим, чтобы Python сообщал о попытке изменения размеров прямоугольника в программе, выдавая сообщение об ошибке.
    Перебор всех значений в кортеже
    Для перебора всех значений в кортеже используется цикл for
    , как и при работе со списками:
    dimensions = (200, 50)
    for dimension in dimensions:
    print(dimension)
    Python возвращает все элементы кортежа по аналогии с тем, как это делается со списком:
    200 50
    Замена кортежа
    Элементы кортежа не могут изменяться, но вы можете присвоить новое значение переменной, в которой хранится кортеж. Таким образом, для изменения размеров прямоугольника следует переопределить весь кортеж:
     dimensions = (200, 50)
    print("Original dimensions:")
    for dimension in dimensions:
    print(dimension)
     dimensions = (400, 100)
     print("\nModified dimensions:")
    for dimension in dimensions:
    print(dimension)

    Стиль программирования 79
    Блок в точке  определяет исходный кортеж и выводит исходные размеры.
    В точке  в переменной dimensions сохраняется новый кортеж, после чего в точке
     выводятся новые размеры. На этот раз Python не выдает сообщений об ошибках, потому что замена значения переменной является допустимой операцией:
    Original dimensions:
    200 50
    Modified dimensions:
    400 100
    По сравнению со списками структуры данных кортежей относительно просты.
    Используйте их для хранения наборов значений, которые не должны изменяться на протяжении жизненного цикла программы.
    УПРАЖНЕНИЯ
    4-13 . Шведский стол: меню «шведского стола» в ресторане состоит всего из пяти пунктов .
    Придумайте пять простых блюд и сохраните их в кортеже .
    • Используйте цикл for для вывода всех блюд, предлагаемых рестораном .
    • Попробуйте изменить один из элементов и убедитесь в том, что Python отказывается вносить изменения .
    • Ресторан изменяет меню, заменяя два элемента другими блюдами . Добавьте блок кода, который заменяет кортеж, и используйте цикл for для вывода каждого элемента обновленного меню .
    Стиль программирования
    Итак, вы постепенно начинаете писать более длинные программы, и вам стоит познакомиться с некоторыми рекомендациями по стилевому оформлению кода.
    Не жалейте времени на то, чтобы ваш код читался как можно проще. Понятный код помогает следить за тем, что делает ваша программа, и упрощает изучение вашего кода другими разработчиками.
    Программисты Python выработали ряд соглашений по стилю, чтобы весь код имел хотя бы отдаленно похожую структуру. Научившись писать «чистый» код Python, вы сможете понять общую структуру кода Python, написанного любым другим программистом, соблюдающим те же рекомендации. Если вы рассчитываете когда-нибудь стать профессиональным программистом, привы- кайте соблюдать эти рекомендации уже сейчас, чтобы выработать полезную привычку.
    Рекомендации по стилю
    Когда кто-нибудь хочет внести изменения в язык Python, он пишет документ PEP
    (Python Enhancement Proposal). Одним из самых старых PEP является документ
    PEP 8 с рекомендациями по стилевому оформлению кода. PEP 8 имеет довольно

    1   ...   5   6   7   8   9   10   11   12   ...   53


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