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

  • 16.3. Оператор in

  • 16.4. Сокращенный синтаксис словарей

  • 16.5. setdefault

  • 16.6. Удаление ключей

  • 16.7. Перебор словаря

  • 16.9. Упражнения 1. Создайте словарь info, в котором хранится ваше имя, фамилия и возраст. 16.9. Упражнения 151

  • Функция создает переменную return num % 2is_oddРис. 17.2.

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


    Скачать 5.41 Mb.
    НазваниеХаррисон Мэтт
    АнкорКак устроен Python
    Дата05.02.2022
    Размер5.41 Mb.
    Формат файлаpdf
    Имя файлаКак устроен Python. Харрисон.pdf
    ТипДокументы
    #352210
    страница12 из 21
    1   ...   8   9   10   11   12   13   14   15   ...   21
    143
    Впрочем, будьте осторожны — при попытке обратиться к ключу, отсут- ствующему в словаре, Python выдаст исключение:
    >>> info['Band']
    Traceback (most recent call last):
    File "", line 1, in
    KeyError: 'Band'
    Поскольку для Python характерно явное выражение намерений програм- миста и быстрое выявление сбоев, выдачу исключений можно только приветствовать. Вы знаете, что ключ 'Band'
    отсутствует в словаре. Было бы гораздо хуже, если бы Python возвращал случайное значение для ключа, отсутствующего в словаре. Это привело бы к дальнейшему рас- пространению ошибки в программе и маскировке логического дефекта.
    16.3. Оператор in
    Python предоставляет оператор in
    , который позволяет быстро проверить наличие ключа в словаре:
    >>> 'Band' in info
    False
    >>> 'first' in info
    True
    Как вы уже видели, in также работает с последовательностями. Опера- тор in может использоваться со списком, множеством или строкой для проверки принадлежности:
    >>> 5 in [1, 3, 6]
    False
    >>> 't' in {'a', 'e', 'i'}
    False
    >>> 'P' in 'Paul'
    True
    ПРИМЕЧАНИЕ
    В Python 3 был исключен метод
    .has_key
    , который предоставляет ту же функциональность, что и команда in
    , но работает только со словарями. Любые действия, ведущие к большей универсальности, можно только приветствовать!

    144
    Глава 16. Словари
    Команда in работает с большинством контейнеров. Кроме того, вы можете определить собственные классы, поддерживающие эту команду. Ваш объ- ект должен поддерживать перебор или определять метод
    .__contains__
    16.4. Сокращенный синтаксис словарей
    Метод
    .get словаря получает значение, соответствующее ключу. Метод
    .get также может получать необязательный параметр для значения по умолчанию, если ключ не найден. Если вы хотите, чтобы genre по умол- чанию присваивалось значение 'Rock'
    , это можно сделать так:
    >>> genre = info.get('Genre', 'Rock')
    >>> genre
    'Rock'
    СОВЕТ
    Метод .
    get словарей — один из способов обойти исключение
    KeyError при попытке использования синтаксиса с квадратными скобками для выборки по ключу, отсутствующему в словаре.
    16.5. setdefault
    У словарей есть полезный метод с неудачно выбранным именем
    .setdefault
    . Этот метод имеет такую же сигнатуру, как
    .get
    , и поначалу работает так же: он возвращает значение по умолчанию, если ключ не существует. Кроме того, он также связывает с ключом значение по умол- чанию, если ключ не найден. Так как
    .setdefault возвращает значение, если инициализировать его изменяемым типом (таким, как словарь или список), результат можно будет изменять на месте.
    Метод
    .setdefault может использоваться для создания накопителя или счетчика ключей. Например, если вы хотите подсчитать количество людей с одним именем, это можно сделать так:
    >>> names = ['Ringo', 'Paul', 'John',
    ... 'Ringo']
    >>> count = {}
    >>> for name in names:

    16.5. setdefault
    145
    ... count.setdefault(name, 0)
    ... count[name] += 1
    Без метода
    .setdefault потребовалось бы немного больше кода:
    >>> names = ['Ringo', 'Paul', 'John',
    ... 'Ringo']
    >>> count = {}
    >>> for name in names:
    ... if name not in count:
    ... count[name] = 1
    ... else:
    ... count[name] += 1
    >>> count['Ringo']
    2
    СОВЕТ
    Подобные операции подсчета встречаются настолько часто, что позднее в стандартную библиотеку Python был добавлен класс collections.Counter
    Этот класс позволяет выполнять такие операции в более компактном виде:
    >>> import collections
    >>> count = collections.Counter(['Ringo', 'Paul',
    ... 'John', 'Ringo'])
    >>> count
    Counter({'Ringo': 2, 'Paul': 1, 'John': 1})
    >>> count['Ringo']
    2
    >>> count['Fred']
    0
    Ниже приведен несколько искусственный пример, демонстрирующий изменение результата
    .setdefault
    . Предположим, имеется словарь, связывающий имя музыканта с названием группы, в которой он играл.
    Если человек по имени
    Paul участвует в двух группах, результат должен связывать имя
    Paul со списком, содержащим обе группы:
    >>> band1_names = ['John', 'George',
    ... 'Paul', 'Ringo']
    >>> band2_names = ['Paul']
    >>> names_to_bands = {}
    >>> for name in band1_names:

    146
    Глава 16. Словари
    ... names_to_bands.setdefault(name,
    ... []).append('Beatles')
    >>> for name in band2_names:
    ... names_to_bands.setdefault(name,
    ... []).append('Wings')
    >>> print(names_to_bands['Paul'])
    ['Beatles', 'Wings']
    В развитие темы: без setdefault этот код получился бы более длинным:
    >>> band1_names = ['John', 'George',
    ... 'Paul', 'Ringo']
    >>> band2_names = ['Paul']
    >>> names_to_bands = {}
    >>> for name in band1_names:
    ... if name not in names_to_bands:
    ... names_to_bands[name] = []
    ... names_to_bands[name].\
    ... append('Beatles')
    >>> for name in band2_names:
    ... if name not in names_to_bands:
    ... names_to_bands[name] = []
    ... names_to_bands[name].\
    ... append('Wings')
    >>> print(names_to_bands['Paul'])
    ['Beatles', 'Wings']
    СОВЕТ
    Модуль collections из стандартной библиотеки Python содержит удобный класс — defaultdict
    . Этот класс своим поведением напоминает словарь, но также позволяет задать для ключа в качестве значения по умолчанию произвольную фабрику (factory). Если фабрика по умолчанию отлична от
    None
    , она инициализируется и вставляется как значение каждый раз, когда отсутствует ключ. Предыдущий пример может быть переписан с defaultdict в следующем виде:
    >>> from collections import defaultdict
    >>> names_to_bands = defaultdict(list)
    >>> for name in band1_names:
    ... names_to_bands[name].\
    ... append('Beatles')
    >>> for name in band2_names:

    16.7. Перебор словаря
    147
    ... names_to_bands[name].\
    ... append('Wings')
    >>> print(names_to_bands['Paul'])
    ['Beatles', 'Wings']
    Код с defaultdict получается чуть более понятным, чем с использованием setdefault
    16.6. Удаление ключей
    Другая стандартная операция со словарями — удаление ключей и соот- ветствующих им значений. Для удаления элемента из словаря исполь- зуется команда del
    :
    # Удаление 'Ringo' из словаря
    >>> del names_to_bands['Ringo']
    СОВЕТ
    Python не позволяет добавлять и удалять данные из словаря во время его перебора. В таких ситуациях Python выдает исключение
    RuntimeError
    :
    >>> data = {'name': 'Matt'}
    >>> for key in data:
    ... del data[key]
    Traceback (most recent call last):
    RuntimeError: dictionary changed size during iteration
    16.7. Перебор словаря
    Словари также поддерживают перебор командой for
    . По умолчанию при переборе по словарю вы получаете ключи:
    >>> data = {'Adam': 2, 'Zeek': 5, 'Fred': 3}
    >>> for name in data:
    ... print(name)
    Adam
    Zeek
    Fred

    148
    Глава 16. Словари
    ПРИМЕЧАНИЕ
    У словарей имеется метод
    .keys
    , который тоже перебирает ключи из словаря.
    В Python 3 метод
    .keys возвращает представление (view) — «окно» для про- смотра ключей, находящихся в настоящий момент в словаре. Представление, как и список, может использоваться для перебора. Однако в отличие от спи- ска, он не является копией этих ключей. Если позднее ключ будет удален из словаря, это изменение отразится в представлении — но не в списке.
    Чтобы перебрать значения в словаре, проведите перебор по методу
    .values
    :
    >>> for value in data.values():
    ... print(value)
    2 5
    3
    Результат вызова
    .values также является представлением. Он отражает текущее состояние значений, находящихся в словаре.
    Чтобы получать при переборе как ключ, так и значение, используйте метод
    .items
    , который возвращает представление:
    >>> for key, value in data.items():
    ... print(key, value)
    Adam 2
    Zeek 5
    Fred 3
    Если материализовать представление в список, вы увидите, что список является последовательностью кортежей (ключ, значение) — то, что получает dict для создания словаря:
    >>> list(data.items())
    [('Adam', 2), ('Zeek', 5), ('Fred', 3)]
    СОВЕТ
    Помните, что словарь упорядочивается в порядке вставки ключей. Если вам нужен другой порядок, последовательность перебора необходимо от- сортировать.

    16.7. Перебор словаря
    149
    Встроенная функция sorted возвращает новый отсортированный список для заданной последовательности:
    >>> for name in sorted(data.keys()):
    ... print(name)
    Adam
    Fred
    Zeek
    У функции sorted есть необязательный аргумент reverse для перехода на противоположный порядок вывода:
    >>> for name in sorted(data.keys(),
    ... reverse=True):
    ... print(name)
    Zeek
    Fred
    Adam
    ПРИМЕЧАНИЕ
    Ключи могут относиться к разным типам. Единственное требование к клю- чам — хешируемость. Например, список не является хешируемым, потому что он может изменяться, и Python не может сгенерировать для него хеш, соот- ветствующий текущему содержимому. Если использовать список в качестве ключа, а затем изменить ключ, какое значение должен вернуть словарь — для старого списка, для нового списка, оба сразу? Python не берется гадать и за- ставляет программиста использовать неизменяемые ключи.
    Вы можете вставлять элементы в словарь, используя в качестве ключей целые числа и строки:
    >>> weird = {1: 'first',
    ... '1': 'another first'}
    Обычно смешивать разнотипные ключи не рекомендуется, потому что это делает код менее понятным и усложняет сортировку. Python 3 не сортирует списки со смешанными типами без функции key
    , которая явно указывает
    Python, как следует сравнивать разные типы. Это один из тех случаев, когда
    Python позволяет что-то сделать, но это не значит, что вам стоит пользоваться этой возможностью. Как говорил один из основных разработчиков Python
    Рэймонд Хеттингер (Raymond Hettinger): «Многие вопросы типа “Могу ли

    150
    Глава 16. Словари я сделать x
    на языке Python?” равнозначны вопросу “Могу ли я остановить машину на рельсах, если поблизости нет поезда?” Да, можете. Нет, не стоит».
    @raymondh
    16.8. Итоги
    Эта глава была посвящена словарям. Эта структура данных играет важ- ную роль, потому что она является одним из «строительных блоков»
    Python. Классы, пространства имен и модули — все это во внутренней реализации Python строится на базе словарей.
    Словари обеспечивают быстрый поиск или вставку по ключу. Также возможен поиск по значению, но он выполняется медленно. Если вам часто приходится выполнять эту операцию со словарями, это верный признак кода «с душком» — подумайте об использовании другой струк- туры данных.
    Также были представлены способы изменения словаря. В словаре можно вставлять и удалять ключи, а также проверять принадлежность при по- мощи команды in
    Мы рассмотрели некоторые нетривиальные конструкции, использую- щие
    .setdefault для вставки и возвращения значений за одну операцию.
    Также были представлены специализированные классы словарей
    Counter и defaultdict из модуля collections
    Поскольку словари изменяемы, вы можете удалять из них ключи коман- дой del
    . Также возможет перебор ключей словаря в цикле for
    В Python 3.6 появилось упорядочение элементов в словарях. Ключи упорядочиваются в порядке вставки, а не по алфавиту и не в числовом порядке.
    16.9. Упражнения
    1. Создайте словарь info
    , в котором хранится ваше имя, фамилия и возраст.

    16.9. Упражнения
    151
    2. Создайте пустой словарь phone с подробной информацией о вашем телефоне. Добавьте в словарь данные о размере экрана, объеме па- мяти, ОС, фирме-производителе и т. д.
    3. Напишите абзац текста в строке, заключенной в тройные кавыч- ки. Используйте метод
    .split для создания списка слов. Создайте словарь для хранения счетчика вхождений каждого слова в абзаце.
    4. Посчитайте, сколько раз используется каждое слово в абзаце тек- ста Ральфа Уолдо Эмерсона.
    5. Напишите код для вывода анаграмм (слов, состоящих из тех же букв в другом порядке) из абзаца текста.
    6. Алгоритм PageRank использовался для создания поисковой систе- мы Google. Алгоритм назначает каждой странице ранг, основанный на количестве входящих ссылок. Он получает одно входное значе- ние: список страниц, ссылающихся на другие страницы. Каждой странице изначально назначается ранг 1. Выполняется несколько итераций алгоритма — обычно 10. Для каждой итерации:
    • страница передает свой ранг, разделенный на количество исхо- дящих ссылок, каждой странице, с которой она связана ссылкой;
    • перенесенный ранг умножается на коэффициент затухания, обыч- но равный 0,85.
    Напишите код для выполнения 10 итераций этого алгоритма со спи- ском кортежей входных и выходных ссылок:
    links = [('a', 'b'), ('a', 'c'), ('b', 'c')]

    17
    Функции
    Мы прошли долгий путь без обсуждения функций, которые являются основными структурными элементами программ Python. Функции представляют собой фрагменты кода, выделенные в отдельный блок.
    В примерах уже использовались такие встроенные функции, как dir и help
    (а также классы, которые ведут себя как функции преобразования типа — float
    , int
    , dict
    , list и bool
    ).
    Функцию можно рассматривать как «черный ящик», которому переда- ются входные данные (хотя их наличие не обязательно). Затем «черный ящик» выполняет серию операций и возвращает результат (если функция завершается без вызова return
    , она неявно возвращает
    None
    ). Главным преимуществом функций является возможность повторного использо- вания кода. После того как функция будет определена, вы сможете вы- зывать ее снова и снова. Если в программе имеется код, который должен выполняться многократно, то вместо копирования/вставки вы можете один раз оформить его в виде функции, а затем вызывать эту функцию.
    При этом сокращается объем кода, а сама программа становится более понятной. Кроме того, становится проще вносить изменения (и исправ- лять ошибки), поскольку это делается в одном месте.
    Рассмотрим простой пример функции. Эта функция с именем add_2
    получает на входе число, прибавляет к нему 2 и возвращает результат:
    >>> def add_2(num):
    ... '''
    ... return 2 more than num
    ... '''
    ... result = num + 2
    ... return result

    Функции
    153
    Функции
    Выходные данные
    Входные данные
    Функция
    Рис. 17.1. Функция работает как «черный ящик»: она получает входные данные и выдает результат (выходные данные). Функции можно передавать при вызове других функций, а также использовать повторно
    Функции
    Код
    Что делает компьютер
    Переменные Объекты dunders ....
    Id:4f3b
    Type:Function def is_odd(num):
    Функция создает переменную
    return num % 2
    is_odd
    Рис. 17.2. Создание функции. Обратите внимание: Python создает новый объект функции, а затем сохраняет указатель на него в переменной с именем функции.
    Для просмотра атрибутов только что созданной функции можно вызвать функцию dir для имени функции

    154
    Глава 17. Функции
    Из каких частей состоит функция? Весь фрагмент кода называется опре-
    делением функции. Определение начинается с команды def
    (сокращение от define, то есть «определение»). За def следует обязательный пробел
    (достаточно одного) и имя функции — add_2
    . Это имя будет исполь- зоваться для вызова функции (то есть ее выполнения). При создании функции Python создаст новую переменную, имя которой совпадает с именем функции.
    За именем функции следует открывающая круглая скобка, за которой следует num и закрывающая круглая скобка. Имена между скобками (их может быть сколько угодно, хотя в данном случае имя только одно) определяют входные параметры — объекты, передаваемые функции.
    За круглыми скобками следует двоеточие (
    :
    ). Когда вы видите двоеточие в Python, за ним почти наверняка следует блок с отступом — по аналогии с телом цикла for
    (см. выше). Весь код с отступом образует тело функции.
    В теле функции содержится вся логика. Вероятно, вы узнаете в первых трех строках кода с отступом конструкцию строки в тройных кавычках.
    Это не комментарий, хотя выглядит похоже, это строка. Python позволяет разместить непосредственно после
    :
    строку, которая называется строкой
    документации. Строка документации используется исключительно для до- кументирования кода. В ней должно содержаться описание блока кода, сле- дующего за ней. Строка документации никак не влияет на логику функции.
    СОВЕТ
    Функция help неоднократно упоминалась в этой книге. Важно отметить, что эта функция получает информацию из строки документации переданного объекта. Если вызвать help для add_2
    , вы получите следующий результат
    (при условии, что вы ввели код add_2
    , приведенный выше):
    >>> help(add_2)
    Help on function add_2 in module
    __main__:
    add_2()
    return 2 more than num
    (END)
    Строки документации напомнят вам, что делает ваш код. Содержательные и точные, они предоставят бесценную информацию каждому, кто захочет использовать ваш код.

    17.1. Вызов функций
    155
    После строки документации (обратите внимание: строка документации не является обязательной) следует логика функции. Здесь вычисляется результат. Наконец, команда return сообщает, что у функции имеется результат, то есть выходное значение. Команда return не является обя- зательной, и при ее отсутствии функция по умолчанию возвращает
    None
    Функция может содержать несколько команд return
    , и они даже не обя- заны находиться в конце функции. Например, условная команда может содержать две команды return
    : в блоке if и в блоке else
    Подведем итог. Основные части функции:
    
    Ключевое слово def
    
    Имя функции.
    
    Параметры функции в круглых скобках.
    
    Двоеточие (
    :
    ).
    
    Отступ:
    • Строка документации.
    • Логика.
    • Команда return
    Создать функцию несложно. Функции позволяют повторно использо- вать код, отчего код становится более коротким и понятным. Функции помогают исключить глобальное состояние, заменяя его переменными с коротким сроком жизни в теле функции. Используйте функции для улучшения структуры кода.
    1   ...   8   9   10   11   12   13   14   15   ...   21


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