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

  • 4.3. Считаем до 20

  • 4.5. Суммирование миллиона чисел

  • 4.6. Нечетные числа

  • УПРАЖНЕНИЯ 4.10. Сегменты

  • УПРАЖНЕНИЯ 4.13. Шведский стол

  • Мэтиз. Изучаем Python. Crash course2 n d e d i t i o na h a n d s o n, p r o j e c t b a s e d i n t r o d u c t i o n t o p r o g r a m m i n g


    Скачать 6.2 Mb.
    НазваниеCrash course2 n d e d i t i o na h a n d s o n, p r o j e c t b a s e d i n t r o d u c t i o n t o p r o g r a m m i n g
    Дата28.06.2022
    Размер6.2 Mb.
    Формат файлаpdf
    Имя файлаМэтиз. Изучаем Python.pdf
    ТипДокументы
    #618322
    страница9 из 52
    1   ...   5   6   7   8   9   10   11   12   ...   52
    74 Глава 4 • Работа со списками
    Простая статистика с числовыми списками
    Некоторые функции Python предназначены для работы с числовыми списками.
    Например, вы можете легко узнать минимум, максимум и сумму числового списка:
    >>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    >>> min(digits)
    0
    >>> max(digits)
    9
    >>> sum(digits)
    45
    ПРИМЕЧАНИЕ В примерах этой главы используются короткие списки чисел, но это делается только для того, чтобы данные помещались на странице . Примеры также бу- дут работать и в том случае, если список содержит миллионы чисел .
    Генераторы списков
    Описанный выше способ генерирования списка squares состоял из трех или четырех строк кода. Генератор списка (list comprehension) позволяет сгенерировать тот же список всего в одной строке. Генератор списка объединяет цикл 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]
    Чтобы успешно писать собственные генераторы списков, необходим опреде- ленный опыт. Тем не менее, как только вы освоитесь с созданием обычных

    Работа с частью списка 75
    списков, вы оцените возможности генераторов. Когда после очередного трех- четырехстрочного блока вам это надоест, подумайте о написании собственных генераторов списков.
    УПРАЖНЕНИЯ
    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 кубов.
    Работа с частью списка
    В главе 3 вы узнали, как обращаться к отдельным элементам списка, а в этой главе мы занимались перебором всех элементов списка. Также можно работать с конкрет- ным подмножеством элементов списка; в Python такие подмножества называются
    сегментами (slices).
    Создание сегмента
    Чтобы создать сегмент на основе списка, следует задать индексы первого и послед- него элементов, с которыми вы намереваетесь работать. Как и в случае с функцией range()
    , Python останавливается на элементе, предшествующем второму индексу.
    Скажем, чтобы вывести первые три элемента списка, запросите индексы с 0 по 3, и вы получите элементы 0, 1 и 2.
    В следующем примере используется список игроков команды:
    players.py
    players = ['charles', 'martina', 'michael', 'florence', 'eli']

    print(players[0:3])

    76 Глава 4 • Работа со списками
    В точке  выводится сегмент, включающий только первых трех игроков. Вывод сохраняет структуру списка, но включает только первых трех игроков:
    ['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:])
    Python возвращает все элементы с третьего до конца списка:
    ['michael', 'florence', 'eli']
    Этот синтаксис позволяет вывести все элементы от любой позиции до конца спи- ска независимо от его длины. Вспомните, что отрицательный индекс возвращает элемент, находящийся на заданном расстоянии от конца списка; следовательно, вы можете получить любой сегмент от конца списка. Например, чтобы отобрать последних трех игроков из списка, используйте сегмент players[-3:]
    :
    players = ['charles', 'martina', 'michael', 'florence', 'eli']
    print(players[-3:])
    Программа выводит имена трех последних игроков, причем продолжает работать даже при изменении размера списка.

    Работа с частью списка 77
    ПРИМЕЧАНИЕ В квадратные скобки, определяющие сегмент, также можно включить третье значение . Это значение, если оно присутствует, сообщает Python, сколько эле- ментов следует пропускать при выборе элементов в заданном диапазоне .
    Перебор содержимого сегмента
    Если вы хотите перебрать элементы, входящие в подмножество элементов, исполь- зуйте сегмент в цикле 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
    Сегменты приносят огромную пользу во многих ситуациях. Например, при соз- дании компьютерной игры итоговый счет игрока может добавляться в список после окончания текущей партии. После этого программа может получить три лучших результата игрока, отсортировав список по уменьшению и получив сег- мент, включающий только три элемента. При работе с данными сегменты могут использоваться для обработки данных блоками заданного размера. Или при по- строении веб-приложения сегменты могут использоваться для постраничного вывода информации так, чтобы на каждой странице выводился соответствующий объем информации.
    Копирование списка
    Часто разработчик берет существующий список и создает на его основе совершенно новый список. Посмотрим, как работает копирование списков, и рассмотрим одну ситуацию, в которой копирование списка может принести пользу.
    Чтобы скопировать список, создайте сегмент, включающий весь исходный список без указания первого и второго индекса (
    [:]
    ). Эта конструкция создает сегмент, который начинается с первого элемента и завершается последним; в результате создается копия всего списка.
    Представьте, что вы создали список своих любимых блюд и теперь хотите создать отдельный список блюд, которые нравятся вашему другу. Пока вашему другу

    78 Глава 4 • Работа со списками нравятся все блюда из нашего списка, поэтому вы можете создать другой список простым копированием нашего:
    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
    . После этого вывод двух списков наглядно показывает, что каждое блюдо находится в соответствующем списке.
    My favorite foods are:

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

    ['pizza', 'falafel', 'carrot cake', 'ice cream']

    Работа с частью списка 79
    Вывод в точке  показывает, что элемент 'cannoli'
    находится в списке my_foods
    , а элемент 'ice cream'
    в этот список не входит. В точке  видно, что 'ice cream'
    вхо- дит в список friend_foods
    , а элемент 'cannoli'
    в этот список не входит. Если бы эти два списка просто совпадали, то их содержимое уже не различалось бы. Например, вот что происходит при попытке копирования списка без использования сегмента:
    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 в точке , мы зада- ем 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. Сегменты: добавьте в конец одной из программ, написанных в этой главе, фрагмент, который делает следующее:
    • Выводит сообщение «The irst three items in the list are:», а затем использует сегмент для вывода первых трех элементов из списка.
    • Выводит сообщение «Three items from the middle of the list are:», а затем использует сегмент для вывода первых трех элементов из середины списка.
    • Выводит сообщение «The last three items in the list are:», а затем использует сегмент для вывода последних трех элементов из списка.

    80 Глава 4 • Работа со списками
    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
    , при этом вместо квадратных скобок используются круглые. В точке  каждый элемент кортежа выводится по отдельно- сти с использованием того же синтаксиса, который использовался для обращения к элементу списка:
    200 50

    Кортежи 81
    Посмотрим, что произойдет при попытке изменения одного из элементов в кортеже 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 сообщал о попытке изменения размеров прямоугольника в программе, выдавая сообщение об ошибке.
    ПРИМЕЧАНИЕ Формально кортеж определяется наличием запятой; круглые скобки просто делают запись более аккуратной и понятной . Если вы хотите определить кортеж, состоящий из одного элемента, включите завершающую запятую:
    my_t = (3,)
    Обычно создание кортежа из одного элемента не имеет особого смысла . Тем не менее это может произойти при автоматическом генерировании кортежей .
    Перебор всех значений в кортеже
    Для перебора всех значений в кортеже используется цикл for
    , как и при работе со списками:
    dimensions = (200, 50)
    for dimension in dimensions:
    print(dimension)
    Python возвращает все элементы кортежа по аналогии с тем, как это делается со списком:
    200 50
    Замена кортежа
    Элементы кортежа не могут изменяться, но вы можете присвоить новое значение переменной, в которой хранится кортеж. Таким образом, для изменения размеров прямоугольника следует переопределить весь кортеж:

    82 Глава 4 • Работа со списками

    dimensions = (200, 50)
    print("Original dimensions:")
    for dimension in dimensions:
    print(dimension)

    dimensions = (400, 100)

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

    Стиль программирования
    1   ...   5   6   7   8   9   10   11   12   ...   52


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