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

  • Этап 1: Сначала переменная указывает на c

  • Этап 4: Символы c и a уничтожаются, символ t остается print(letter)Вывод ca tРис. 15.2.

  • ПРИМЕЧАНИЕ Блок if внутри блока for снабжен отступом из восьми пробелов. Блоки могут быть вложенными, и каждый уровень должен иметь свой отступ.15.3. Пропуск элементов в цикле

  • 15.4. Оператор in может использоваться для проверки принадлежности

  • 15.5. Удаление элементов из списков при переборе

  • 16.1. Присваивание в словарях

  • 16.2. Выборка значений из словаря

  • Словари не копируют данные info = {name : first}firstPeterStr infonameStrРис. 16.1.

  • Как устроен Python. Как устроен Python. Харрисон. Харрисон Мэтт


    Скачать 5.41 Mb.
    НазваниеХаррисон Мэтт
    АнкорКак устроен Python
    Дата05.02.2022
    Размер5.41 Mb.
    Формат файлаpdf
    Имя файлаКак устроен Python. Харрисон.pdf
    ТипДокументы
    #352210
    страница11 из 21
    1   ...   7   8   9   10   11   12   13   14   ...   21
    14.10. Упражнения
    1. Создайте список, сохраните в нем имена ваших коллег и друзей.
    Изменился ли идентификатор списка? Отсортируйте список. Ка- кой элемент стоит в начале списка? Какой элемент является вто- рым?

    14.10. Упражнения
    129
    2. Создайте кортеж с вашим именем, фамилией и возрастом. Соз- дайте список people и присоедините к нему свой кортеж. Создайте другие кортежи с соответствующей информацией о ваших друзьях и присоедините их к списку. Отсортируйте список. Когда в книге будут рассмотрены функции, вы сможете использовать параметр key для сортировки списка по любому полю кортежа: имени, фами- лии или возрасту.
    3. Создайте список с именами ваших друзей. Создайте список с деся- тью самыми популярными именами. При помощи операций мно- жеств проверьте, входят ли имена кого-либо из ваших друзей в этот список.
    4. Посетите сайт проекта «Гутенберг»
    1
    и найдите страницу текста из
    Шекспира. Вставьте текст в строку, заключенную в тройные ка- вычки. Создайте другую строку с абзацем текста из Ральфа Уолдо
    Эмерсона. Используйте метод
    .split строк для получения списка слов из каждого текста. При помощи операций с множествами най- дите общие слова, встречающиеся в текстах обоих авторов, а также слова, уникальные для каждого автора.
    5. Кортежи и списки похожи, но обладают разным поведением. Ис- пользуйте операции с множествами для нахождения атрибутов объекта списка, отсутствующих у объекта кортежа.
    1
    https://www.gutenberg.org/

    15
    Итерации
    Одна из стандартных идиом при работе с последовательностями — пере- бор содержимого последовательности. Например, вы можете отфиль- тровать один из элементов, применить к элементам функцию, вывести элементы и т. д. Для решения этой задачи можно воспользоваться цик- лом for
    . В следующем примере выводятся все строки из списка:
    >>> for letter in ['c', 'a', 't']:
    ... print(letter)
    c a
    t
    >>> print(letter)
    t
    ПРИМЕЧАНИЕ
    Обратите внимание: конструкция цикла for содержит двоеточие (
    :
    ), за ко- торым следует код с отступом (блок цикла for
    ).
    В цикле for
    Python создает новую переменную letter для хранения текущего элемента. Обратите внимание: в letter хранится не индекс, а строка. Python не очищает переменную после завершения цикла.

    15.1. Перебор с индексом
    131
    15.1. Перебор с индексом
    В таких языках, как C, перебор в последовательностях ведется не по элементам последовательности, а по индексам. Используя индексы, вы можете извлекать элементы с указанными индексами. Ниже показан один из вариантов решения этой задачи с использованием встроенных функций Python range и len
    :
    >>> animals = ["cat", "dog", "bird"]
    >>> for index in range(len(animals)):
    ... print(index, animals[index])
    0 cat
    1 dog
    2 bird
    Приведенный выше фрагмент содержит код с душком: этот термин обыч- но подразумевает, что вы используете Python не так, как следовало бы.
    Обычно перебор в последовательностях выполняется для получения доступа к элементам последовательности, а не к индексам. Тем не менее в отдельных случаях индекс тоже бывает нужен. Python предоставля- ет встроенную функцию enumerate
    , с которой комбинация range и len становится излишней. Функция enumerate возвращает кортеж (индекс,
    элемент) для каждого элемента в последовательности:
    >>> animals = ["cat", "dog", "bird"]
    >>> for index, value in enumerate(animals):
    ... print(index, value)
    0 cat
    1 dog
    2 bird
    Так как кортеж содержит пару из индекса и значения, вы можете вос- пользоваться распаковкой кортежа для создания двух переменных, index и value
    , прямо в цикле for
    . Имена переменных должны разделять- ся запятой. Если длина кортежа совпадает с количеством переменных, включаемых в цикл for
    , Python создаст их за вас.

    132
    Глава 15. Итерации
    Создание переменной в цикле for
    [ , , ]
    Id:4f3b
    Type:List letter
    'c'
    Str for letter in ['c', 'a', 't']:
    'a'
    Str
    't'
    Str
    Этап 1: Сначала переменная указывает на c
    print(letter)
    Вывод
    Вывод c
    [ , , ]
    Id:4f3b
    Type:List letter
    'c'
    Str for letter in ['c', 'a', 't']:
    'a'
    Str
    't'
    Str
    Этап 2: Затем переменная указывает на a
    print(letter)
    c a
    Команда
    Что делает компьютер
    Переменные Объекты
    Рис. 15.1. Создание переменной в цикле for. Создается новая переменная letter; сначала она указывает на символ 'c', который выводится вызовом print.
    Затем цикл переходит на следующую итерацию, и переменная указывает на 'a'

    15.1. Перебор с индексом
    133
    [ , , ]
    Id:4f3b
    Type:List letter
    'c'
    Str for letter in ['c', 'a', 't']:
    'a'
    Str
    't'
    Str
    Этап 3: Наконец, letter указывает на t,
    список уничтожается
    print(letter)
    Вывод c
    a t
    [ , , ]
    Id:4f3b
    Type:List letter
    'c'
    Str for letter in ['c', 'a', 't']:
    'a'
    Str
    't'
    Str
    Этап 4: Символы c и a уничтожаются,
    символ t остается
    print(letter)
    Вывод c
    a t
    Рис. 15.2. Цикл for продолжается, а после вывода 't' он завершается. В этот момент литерал списка уничтожается в ходе уборки мусора. Так как на 'c' и 'a' указывает только список, они тоже уничтожаются. Однако переменная letter продолжает указывать на 't'. Python не уничтожает эту переменную, и она продолжит существовать после завершения цикла for

    134
    Глава 15. Итерации
    15.2. Выход из цикла
    Иногда бывает нужно прервать выполнение цикла преждевременно, до перебора всех элементов в цикле. Ключевое слово break прерывает ближайший внутренний цикл, в котором вы находитесь. Следующая про- грамма суммирует числа до тех пор, пока не обнаружит отрицательное число. В этом случае выполнение цикла прерывается командой break
    :
    >>> numbers = [3, 5, 9, -1, 3, 1]
    >>> result = 0
    >>> for item in numbers:
    ... if item < 0:
    ... break
    ... result += item
    >>> print(result)
    17
    ПРИМЕЧАНИЕ
    В строке result += item используется так называемое расширенное присваивание. Эта команда эк- вивалентна:
    result = result + item
    Расширенное присваивание выполняется чуть быстрее, так как выборка для переменной result выполняется всего один раз. Кроме того, команда полу- чается более компактной и быстрее вводится.
    ПРИМЕЧАНИЕ
    Блок if внутри блока for снабжен отступом из восьми пробелов. Блоки могут быть вложенными, и каждый уровень должен иметь свой отступ.
    15.3. Пропуск элементов в цикле
    Другая стандартная идиома циклов — пропуск отдельных элементов при переборе. Если выполнение тела цикла for занимает некоторое время, а выполняться оно должно только для некоторых элементов последова-

    15.5. Удаление элементов из списков при переборе
    135
    тельности, вам пригодится ключевое слово continue
    . Команда continue приказывает Python прервать обработку текущего элемента цикла и про- должить цикл от начала блока for со следующим значением в цикле.
    В следующем примере суммируются все положительные числа из списка:
    >>> numbers = [3, 5, 9, -1, 3, 1]
    >>> result = 0
    >>> for item in numbers:
    ... if item < 0:
    ... continue
    ... result = result + item
    >>> print(result)
    21
    15.4. Оператор in может использоваться
    для проверки принадлежности
    Мы использовали команду in в цикле for
    . В языке Python эта команда также может использоваться для проверки принадлежности. Если вы хотите узнать, содержит ли список заданный элемент, используйте коман ду in для проверки:
    >>> animals = ["cat", "dog", "bird"]
    >>> 'bird' in animals
    True
    Если вам потребуется узнать индекс, используйте метод
    .index
    :
    >>> animals.index('bird')
    2
    15.5. Удаление элементов из списков
    при переборе
    Как уже упоминалось ранее, списки являются изменяемыми. Изменяе- мость означает, что в них можно добавлять или удалять элементы. Кроме того, списки являются последовательностями, а значит, их содержимое можно перебирать.

    136
    Глава 15. Итерации
    Например, если вы захотите отфильтровать список имен так, чтобы в нем остался только элемент 'John'
    или 'Paul'
    , делать это так было бы неправильно:
    >>> names = ['John', 'Paul', 'George',
    ... 'Ringo']
    >>> for name in names:
    ... if name not in ['John', 'Paul']:
    ... names.remove(name)
    >>> print(names)
    ['John', 'Paul', 'Ringo']
    Что произошло? Python предполагает, что списки не изменяются в процессе перебора. Добравшись до 'George'
    , цикл удаляет имя из списка. Во внутренней реализации Python отслеживает текущий ин- декс цикла for
    . На этот момент в списке остаются только три элемента:
    'John'
    ,
    'Paul'
    и 'Ringo'
    . Однако цикл for думает, что текущей является позиция с индексом 3 (четвертый элемент), а четвертого элемента не существует, поэтому цикл останавливается, и элемент 'Ringo'
    остается на месте.
    Существует два альтернативных решения для удаления элементов из списка в процессе перебора. В первом варианте удаляемые элементы отбираются при первом проходе по списку. Следующий цикл перебира- ет только те элементы, которые подлежат удалению (
    names_to_remove
    ), и удаляет их из исходного списка (
    names
    ):
    >>> names = ['John', 'Paul', 'George',
    ... 'Ringo']
    >>> names_to_remove = []
    >>> for name in names:
    ... if name not in ['John', 'Paul']:
    ... names_to_remove.append(name)
    >>> for name in names_to_remove:
    ... names.remove(name)
    >>> print(names)
    ['John', 'Paul']

    15.7. Циклы while
    137
    Другое решение — перебор по копии списка. Оно довольно легко реали- зуется конструкцией копирования среза
    [:]
    , которая будет рассмотрена в главе, посвященной срезам:
    >>> names = ['John', 'Paul', 'George',
    ... 'Ringo']
    >>> for name in names[:]: # copy of names
    ... if name not in ['John', 'Paul']:
    ... names.remove(name)
    >>> print(names)
    ['John', 'Paul']
    15.6. Блок else
    Цикл for также может содержать блок else
    . Любой код в блоке else будет выполнен в том случае, если цикл for не достиг команды break
    Сле дующий пример проверяет, являются ли числа из цикла положи- тельными:
    >>> positive = False
    >>> for num in items:
    ... if num < 0:
    ... break
    ... else:
    ... positive = True
    Команды continue не влияют на выполнение блока else
    Имя команды else выглядит несколько странно. Для цикла for она по- казывает, что была обработана вся последовательность. Блок else в цикле for часто применяется для обработки отсутствия элементов.
    15.7. Циклы while
    Python позволяет многократно выполнять блок кода, пока некоторое условие остается истинным. Такая конструкция называется циклом while, а для ее создания используется команда while
    . За циклом while следует

    138
    Глава 15. Итерации выражение, результат которого равен
    True или
    False
    , а за выражением идет двоеточие. Помните, что следует за двоеточием (
    :
    ) в Python? Да, блок кода с отступом. Этот блок продолжит выполняться, пока результат выражения остается равным
    True
    . В программе может легко возникнуть бесконечный цикл.
    Бесконечные циклы обычно нежелательны, потому что ваша програм- ма «зависает» в цикле без возможности выхода. Впрочем, у правила есть исключения: например, сервер в бесконечном цикле принимает и обрабатывает запросы. Другое исключение, встречающееся в коде
    Python более высокого уровня, — бесконечный генератор. Генератор ведет себя как отложенный список, который создает значения только тогда, когда они будут задействованы в переборе. Если вы знакомы с обработкой потоков, генератор можно рассматривать как поток.
    (Генераторы в этой книге не рассматриваются, но я опишу их в книге более высокого уровня.)
    Как правило, если у вас имеется объект, поддерживающий перебор, для перебора элементов используется цикл for
    . Циклы while используются при отсутствии простого доступа к объекту, поддерживающему перебор.
    Типичный пример использования цикла while
    — обратный отсчет:
    >>> n = 3
    >>> while n > 0:
    ... print(n)
    ... n = n - 1 3
    2 1
    Для выхода из цикла while также может использоваться команда break
    :
    >>> n = 3
    >>> while True:
    ... print(n)
    ... n = n - 1
    ... if n == 0:
    ... break

    15.9. Упражнения
    139
    15.8. Итоги
    В этой главе рассматривается использование циклов for для перебора элементов последовательности. Вы видели, что в цикле можно вести перебор по спискам; также возможен перебор по строкам, кортежам, сло- варям и другим структурам данных. Более того, вы можете определять собственные классы, поддерживающие перебор в циклах for
    , реализуя метод
    .__iter__
    Цикл for создает переменную при переборе. Эта переменная не унич- тожается после цикла, а продолжает существовать. Если цикл for вы- полняется внутри функции, переменная будет уничтожена при выходе из функции.
    Также в этой главе была представлена функция enumerate
    . Функция возвращает последовательность кортежей (пар «индекс, значение») для переданной последовательности. Если вам понадобится получить при переборе как индекс, так и значение, используйте enumerate
    Наконец, вы узнали, как прервать выполнение цикла, перейти к следу- ющему элементу или использовать команду else
    . Все эти конструкции позволяют адаптировать логику циклов для конкретных задач.
    15.9. Упражнения
    1. Создайте список с именами друзей и коллег. Вычислите среднюю длину имен в списке.
    2. Создайте список с именами друзей и коллег. Проведите поиск име- ни
    John в списке в цикле for
    . Если имя не найдено, выведите соот- ветствующее сообщение (подсказка: используйте else
    ).
    3. Создайте список кортежей из имени, фамилии и возраста ваших друзей и коллег. Если возраст неизвестен, занесите значение
    None
    Вычислите средний возраст, пропустив все значения
    None
    . Выведи- те каждое имя, за которым следует строка
    Old
    (возраст выше сред- него) или
    Young
    (возраст ниже среднего).

    16
    Словари
    Словари (dictionaries) — высокооптимизированный встроенный тип в языке Python. Словарь Python отчасти напоминает обычный словарь, состоящий из слов и определений. Задача словаря — обеспечить быстрый поиск определения по ключевому слову. В обычном словаре для ускоре- ния поиска можно воспользоваться методом бинарного поиска (открыть словарь на середине, определить, в какой половине находится искомое слово, и повторить).
    Словарь Python тоже состоит из слов и определений, но они называют- ся ключами и значениями соответственно. Цель словаря — обеспечить быстрый поиск по ключу и извлечь значение, связанное с этим ключом.
    Как и в обычном словаре, в котором нахождение слова по определению займет много времени (если вы заранее не знаете искомое слово), поиск по значению в словаре Python происходит очень медленно.
    В Python 3.6 у словарей появилась новая особенность: ключи теперь сорти- руются по порядку вставки. Если вы пишете код Python, который должен работать в предыдущих версиях, вы должны запомнить, что до версии 3.6 порядок ключей был произвольным (что позволяло Python выполнять быстрый поиск, но было не особо полезно для конечного пользователя).
    16.1. Присваивание в словарях
    Словари связывают ключ со значением (в других языках программиро- вания они могут называться хешами, хеш-картами, картами или ассо-

    16.1. Присваивание в словарях
    141
    циативными массивами). Допустим, вы хотите сохранить информацию о человеке. Вы уже видели, как использовать кортеж для представления записи. Словари тоже могут использоваться для решения этой задачи. Так как словари встроены в Python, для их создания можно воспользоваться синтаксисом литералов. В следующем словаре хранится имя и фамилия:
    >>> info = {'first': 'Pete', 'last': 'Best'}
    ПРИМЕЧАНИЕ
    Также словарь можно создать при помощи встроенного класса dict
    . Если передать классу список пар кортежей, он вернет словарь:
    >>> info = dict([('first', 'Pete'),
    ... ('last', 'Best')])
    При вызове dict также можно использовать именованные параметры:
    >>> info = dict(first='Pete', last='Best')
    Если вы используете именованные параметры, они должны быть допустимы- ми именами переменных Python, тогда они будут преобразованы в строки.
    Для вставки значений в словарь можно воспользоваться индексными операциями:
    >>> info['age'] = 20
    >>> info['occupation'] = 'Drummer'
    В этом примере ключами являются 'first'
    ,
    'last'
    ,
    'age'
    и 'occupation'
    Например,
    'age'
    ключ, которому соответствует значение: целое чис- ло 20. Чтобы быстро найти значение, соответствующее 'age'
    , выполните поиск индексной операцией:
    >>> info['age']
    20
    С другой стороны, если вам потребуется определить, какой ключ со- ответствует значению 20, такая операция будет слишком медленной.
    В приведенном примере продемонстрирован синтаксис литералов для создания изначально заполненного словаря. Пример также показывает, как квадратные скобки (индексные операции) используются для вставки

    142
    Глава 16. Словари элементов в словарь и их извлечения. Индексная операция связывает ключ со значением при использовании в сочетании с оператором при-
    сваивания (
    =
    ). Если индексная операция не содержит присваивания, она находит значение, соответствующее заданному ключу.
    16.2. Выборка значений из словаря
    Как вы уже видели, синтаксис литералов с квадратными скобками может извлечь значение из словаря при использовании квадратных скобок без присваивания:
    >>> info['age']
    20
    Словари
    Код
    Что делает компьютер
    Переменные Объекты
    { : }
    Id:4f3b
    Type:Dict first = 'Peter'
    Словари не копируют данные
    info = {'name' : first}
    first
    'Peter'
    Str info
    'name'
    Str
    Рис. 16.1. Создание словаря. В данном случае в качестве значения используется существующая переменная. Обратите внимание: словарь не копирует переменную, но создает указатель на нее (увеличивая ее счетчик ссылок)

    16.3. Оператор in
    1   ...   7   8   9   10   11   12   13   14   ...   21


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