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

  • Выражение

  • Поиск информативных слов с помощью спискового включения

  • Общее описание

  • однострочники пайтон. Однострочники Python лаконичный и содержательный код by Кристи. Однострочники


    Скачать 4.44 Mb.
    НазваниеОднострочники
    Анкороднострочники пайтон
    Дата22.04.2022
    Размер4.44 Mb.
    Формат файлаpdf
    Имя файлаОднострочники Python лаконичный и содержательный код by Кристи.pdf
    ТипКнига
    #490720
    страница4 из 21
    1   2   3   4   5   6   7   8   9   ...   21
    38
    Глава 1. Краткая памятка по Python
    Листинг 1.13. Использование ключевого слова continue while True:
    continue print("43") # недостижимый код
    Данный код выполняется бесконечно, но оператор print не выполняется ни- когда. Дело в том, что оператор continue завершает текущую итерацию цикла и возвращает поток выполнения в его начало, поэтому print никогда не до- стигается. Подобный никогда не выполняемый код называется недостижимым
    (dead code). Поэтому оператор continue
    (как и оператор break
    ) часто приме- няется при определенных условиях в среде условного выполнения if-else
    Функции
    Функции позволяют при необходимости повторно использовать фрагменты кода: писать их один раз, а задействовать многократно. При описании функ- ции указывается ключевое слово def
    , название функции и набор аргументов для параметризации выполнения ее тела. Различные наборы аргументов могут резко менять возвращаемые функцией результаты. Допустим, вы описали функцию square(x)
    , возвращающую квадрат входного аргумента x
    Вызов square(10)
    возвращает
    10
    ×
    10
    =
    100
    , а вызов square(100)
    возвращает
    100
    ×
    100
    =
    10000
    Ключевое слово return завершает выполнение функции и передает поток выполнения вызывающей стороне. Можно также указать необязательное значение после ключевого слова return
    , содержащее возвращаемый функ- цией результат (листинг 1.14).
    Листинг 1.14. Ключевое слово return def appreciate(x, percentage):
    return x + x * percentage / 100
    print(appreciate(10000, 5))
    # 10500.0
    Мы создали функцию appreciate()
    для вычисления роста вклада при за- данной доходности. В приведенном коде мы вычисляем, насколько растет вклад 10 000 долларов за один год при ставке 5 %. В результате получается
    10 500 долларов. С помощью ключевого слова return указываем, что резуль- тат функции должен равняться сумме исходного вклада и номинальной про- центной ставки. Тип возвращаемого значения функции appreciate()
    — float.

    Итоги главы
    39
    Лямбда-функции
    С помощью ключевого слова lambda в языке Python можно задавать лямбда-
    функции — анонимные функции, не описанные в пространстве имен. Если не вдаваться в подробности, то это функции без названия, предназначенные для однократного использования. Синтаксис их выглядит так:
    lambda <аргументы> : <возвращаемое выражение>
    У лямбда-функции может быть один или несколько аргументов, разделен- ных запятыми. После двоеточия (
    :
    ) описывается возвращаемое выражение, в котором может использоваться (или не использоваться) описанный ранее аргумент. Роль возвращаемого выражения может играть любое выражение или даже другая функция.
    Лямбда-функции играют важнейшую роль в Python. В коде реальных про- ектов они встречаются повсеместно: например, для сокращения кода или создания аргументов различных функций Python (например, map()
    или reduce()
    ). Рассмотрим код в листинге 1.15.
    Листинг 1.15. Использование ключевого слова lambda print((lambda x: x + 3)(3))
    # 6
    Сначала мы создаем лямбда-функцию, принимающую на входе значение x
    и возвращающую результат выражения x
    +
    3
    . Результат представляет со- бой объект-функцию, которую можно вызывать точно так же, как любую другую. В соответствии с ее семантикой эту функцию можно назвать функ-
    цией-инкрементором. Результат ее вызова с аргументом x=3
    — суффикс
    (3)
    в операторе print в листинге 1.15 — целочисленное значение
    6
    . В книге мы будем постоянно использовать лямбда-функции, поэтому убедитесь, что хорошо понимаете, как они работают (хотя у вас еще будет возможность тщательнее разобраться в них).
    Итоги главы
    В этой главе вы освежили свои знания Python благодаря приведенному краткому экспресс-курсу. Вы посмотрели на важнейшие структуры данных
    Python и их использование в примерах кода. Научились управлять пото- ком выполнения программы с помощью операторов if-elif-else
    , а также

    40
    Глава 1. Краткая памятка по Python циклов for и while
    . Вы повторили основные типы данных Python — Boolean, integer, float и string — и узнали, какие встраиваемые операции и функции часто применяются для работы с ними. В основе большинства фрагментов кода и нетривиальных алгоритмов на практике лежат обладающие большими возможностями контейнерные типы данных, такие как списки, стеки, мно- жества и ассоциативные массивы. Из приведенных примеров вы научились добавлять, удалять, вставлять и переупорядочивать элементы. Вы также узнали об операторах принадлежности и списковом включении: эффек- тивном и обладающем большими возможностями методе программного создания списков в Python. Наконец, вы узнали о функциях и научились их описывать (включая анонимные лямбда-функции). Теперь вы готовы рассмотреть первые десять простейших однострочников Python.

    2
    Трюки Python
    Трюками мы будем называть способы необычайно быстрого или легкого решения задач. В книге вы встретите массу различных трюков и методик повы- шения лаконичности кода, которые к тому же позволят ускорить его реализацию. Хотя приемы Python встре- тятся вам во всех технических главах данной книги, эта по- священа самому очевидному: трюкам, существенно ускоряющим написание кода, которые можно взять на вооружение быстро и без особых усилий.
    Эта глава также играет роль фундамента для последующих, более продви- нутых глав. Для понимания материала, который будет изложен далее, вам необходимо освоить навыки, заложенные в однострочниках из текущей главы. В частности, мы охватим широкий спектр простейшей функциональ- ности Python, благодаря которой можно писать эффективный код, в том числе списковые включения, доступ к файлам, функции map()
    и reduce()
    , лямбда-функции, срезы, присваивание срезам, функции-генераторы и функ- цию zip()
    Если вы уже опытный программист, то можете пролистать эту главу и ре- шить самостоятельно, какие вопросы хотите изучить подробнее, а в каких уже и так хорошо разбираетесь.

    42
    Глава 2. Трюки Python
    Поиск самых высокооплачиваемых работников
    с помощью спискового включения
    В данном разделе вы познакомитесь с прекрасной, очень эффективной и по- лезной возможностью Python для создания списков: списковым включением
    (list comprehension). Оно пригодится нам во множестве однострочников далее в книге.
    Общее описание
    Представьте, что вы работаете в отделе кадров большой компании и вам нужно найти всех сотрудников, зарабатывающих по крайней мере
    100 000 долларов в год. Выходные результаты должны представлять собой список кортежей, каждый из которых состоит из двух значений: имени сотрудника и его годовой зарплаты. Ниже представлен соответствующий код:
    employees = {'Alice' : 100000,
    'Bob' : 99817,
    'Carol' : 122908,
    'Frank' : 88123,
    'Eve' : 93121}
    top_earners = []
    for key, val in employees.items():
    if val >= 100000:
    top_earners.append((key,val))
    print(top_earners)
    # [('Alice', 100000), ('Carol', 122908)]
    И хотя код работает правильно, существует более простой и намного более лаконичный, а значит, и удобочитаемый способ получить тот же результат.
    При прочих равных условиях решение, занимающее меньше строк, будет понятнее для читающего код.
    В Python существует замечательный способ создания новых списков: спи-
    сковое включение. Оно описывается простой формулой:
    [выражение + контекст]
    Внешние квадратные скобки указывают, что результат представляет собой новый список. Контекст указывает, какие элементы списка необходимо

    Поиск самых высокооплачиваемых работников с помощью спискового включения
    43
    взять. Выражение описывает способ модификации элементов списка перед добавлением результата в список. Пример выглядит так:
    [x * 2 for x in range(3)]
    Выделенная жирным шрифтом часть,
    for
    x
    in
    range(3)
    , представляет со- бой контекст, а остальная часть, x
    *
    2
    , — выражение. Выражение удваивает значения
    0
    ,
    1
    ,
    2
    , сгенерированные контекстом. Таким образом, результат спискового включения представляет собой следующий список:
    [0, 2, 4]
    Как выражение, так и контекст могут быть произвольной степени сложно- сти. Выражение может представлять собой функцию от любой описанной в контексте переменной и выполнять любые вычисления — и даже вызывать внешние функции. Задача выражения — модифицировать каждый из эле- ментов списка перед добавлением его в новый список.
    Контекст может состоять из одной или нескольких переменных, описанных с помощью одного или нескольких вложенных циклов for
    . Можно также ограничить контекст, задействовав операторы if
    . В данном случае новое значение добавляется в список только при соблюдении заданного пользо- вателем условия.
    Списковое включение лучше всего пояснить на примере. Внимательно изу- чите следующие примеры, и вы поймете, что оно собой представляет:
    print([x for x in range(5)])
    # [0, 1, 2, 3, 4]
    Выражение : тождественная функция (не меняет контекст переменной x
    ).
    Контекст : переменная контекста x
    принимает все значения, возвращаемые функцией range
    :
    0
    ,
    1
    ,
    2
    ,
    3
    ,
    4
    print([(x, y) for x in range(3) for y in range(3)])
    # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
    Выражение : создает новый кортеж из переменных контекста x
    и y
    Контекст : переменная контекста x
    проходит в цикле по всем значени- ям, возвращаемым функцией range
    (
    0
    ,
    1
    ,
    2
    ); то же делает и переменная контекста y
    . Эти два цикла for
    — вложенные, вследствие чего переменная

    44
    Глава 2. Трюки Python контекста y
    повторяет итерации своего цикла для каждого из значений переменной контекста x
    . Таким образом, получается 3
    × 3 = 9 сочетаний переменных контекста.
    print([x ** 2 for x in range(10) if x % 2 > 0])
    # [1, 9, 25, 49, 81]
    Выражение : функция возведения в квадрат переменной контекста x
    Контекст : переменная контекста x
    проходит в цикле по всем значениям, возвращаемым функцией range

    0
    ,
    1
    ,
    2
    ,
    3
    ,
    4
    ,
    5
    ,
    6
    ,
    7
    ,
    8
    ,
    9
    , — но только нечет- ным, то есть когда x
    %
    2
    >
    0
    print([x.lower() for x in ['I', 'AM', 'NOT', 'SHOUTING']])
    # ['i', 'am', 'not', 'shouting']
    Выражение : строковая функция приведения к нижнему регистру пере- менной контекста x
    Контекст : переменная контекста x
    проходит в цикле по всем строковым значениям в списке:
    'I'
    ,
    'AM'
    ,
    'NOT'
    ,
    'SHOUTING'
    Теперь вы сможете понять, что происходит во фрагменте кода, который будет показан ниже.
    Код
    Рассмотрим уже обсуждавшуюся ранее задачу с зарплатами сотрудников: по ассоциативному массиву со строковыми ключами и целочисленными значениями создать новый список из кортежей (ключ, значение), таких, что соответствующее ключу значение больше или равно 100 000. Соответству- ющий код приведен в листинге 2.1.
    Листинг 2.1. Однострочное решение для спискового включения
    ## Данные employees = {'Alice' : 100000,
    'Bob' : 99817,
    'Carol' : 122908,
    'Frank' : 88123,
    'Eve' : 93121}
    ## Однострочник top_earners = [(k, v) for k, v in employees.items() if v >= 100000]

    Поиск информативных слов с помощью спискового включения
    45
    ## Результат print(top_earners)
    Каковы же будут результаты выполнения этого фрагмента кода?
    Принцип работы
    Рассмотрим этот однострочник подробнее.
    top_earners = [(k, v) for k, v in employees.items() if v >= 100000]
    Выражение : создает простой кортеж (ключ, значение) для переменных контекста k
    и v
    Контекст : метод ассоциативного массива dict.items()
    обеспечивает проход переменной контекста k
    в цикле по всем ключам ассоциативного массива, а переменной контекста v
    — в цикле по соответствующим перемен- ной контекста k
    значениям, но только если значение переменной контекста v
    равно или больше 100 000, в соответствии с условием if
    Результат выполнения этого однострочника выглядит следующим образом:
    print(top_earners)
    # [('Alice', 100000), ('Carol', 122908)]
    В этой простой однострочной программе мы познакомились с важным по- нятием спискового включения. Такие включения используются во многих местах данной книги, поэтому хорошо разберитесь с примерами в текущем разделе, прежде чем читать дальше.
    Поиск информативных слов с помощью
    спискового включения
    В этом однострочнике мы еще более углубимся в изучение обладающей большими возможностями функциональности списковых включений.
    Общее описание
    Поисковые системы ранжируют текстовую информацию по степени соот- ветствия запросу пользователя. Для этого поисковые системы анализируют

    46
    Глава 2. Трюки Python содержимое текста, в котором необходимо произвести поиск. Любой текст состоит из слов. В одних содержится немало информации о содержимом текста, а в других — нет. Примеры первых слов — white, whale, Captain, Ahab
    1
    (узнали, откуда это?). Примеры слов второго типа — is, to, as, the, a и how, поскольку они содержатся в большинстве текстов. При реализации поис- ковых систем часто отфильтровывают слова, не несущие особого значения.
    Простейший эвристический подход — отфильтровывать все слова из трех или менее букв.
    Код
    Наша цель — решить следующую задачу: создать на основе многострочного строкового значения список списков, каждый из которых состоит из всех слов одной из строк, причем слова эти длиной три символа и более. В ли- стинге 2.2 приведены данные и решение.
    Листинг 2.2. Однострочное решение для поиска информативных слов
    ## Данные text = '''
    Call me Ishmael. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen, and regulating the circulation. - Moby Dick'''
    ## Однострочник w = [[x for x in line.split() if len(x)>3] for line in text.split('\n')]
    ## Результат print(w)
    Какими же будут результаты выполнения этого фрагмента кода?
    Принцип работы
    Данный однострочник создает список списков с помощью двух вложенных выражений для спискового включения:
    во внутреннем выражении для спискового включения
    [x for x
    in line.split()
    if len(x)>3]
    используется строковая функция split()
    1
    Белый, кит, капитан, Ахав.

    Чтение файла
    47
    для разбиения заданной строки на последовательность слов. Мы про- ходим по всем словам x
    и добавляем в список те из них, длина которых не менее трех символов;
    во внешнем выражении для спискового включения создается строко- вое значение line
    , используемое в предыдущем операторе. Опять же, для разбиения текста по символам новой строки '\n'
    применяется функция split()
    Конечно, необходимо научиться думать на языке списковых включений, поэтому в первое время они могут показаться сложными. Но когда вы закон- чите читать данную книгу, списковые включения станут для вас обыденными и вы будете быстро писать код на языке Python в подобном стиле.
    Чтение файла
    В этом разделе мы прочитаем данные из файла и сохраним результат в виде списка строковых значений (по одному на строку). Мы также удалим из прочитанных строк все ведущие и хвостовые пробельные символы.
    Общее описание
    В Python чтение файла не представляет трудности, но требует обычно не- скольких строк кода (и кое-какого поиска в Google). Ниже представлен один из стандартных способов чтения данных из файла в языке Python:
    filename = "readFileDefault.py" # этот код f = open(filename)
    lines = []
    for line in f:
    lines.append(line.strip())
    print(lines)
    """
    ['filename = "readFileDefault.py" # этот код',
    '',
    'f = open(filename)',
    'lines = []',
    'for line in f:',
    'lines.append(line.strip())',
    '',
    'print(lines)']
    """

    48
    Глава 2. Трюки Python
    Предполагается, что этот фрагмент кода сохранен в файле readFileDefault.py в текущем каталоге. Код открывает данный файл, создает пустой список, lines
    , и заполняет его строковыми значениями с помощью операции append()
    в теле цикла for
    , в котором проходит по всем строкам файла. Мы также воспользовались строковым методом strip()
    для удаления всех ве- дущих и хвостовых пробельных символов (в противном случае в строках бы оказались и символы новой строки '\n'
    ).
    Для доступа к файлам на компьютере необходимо знать, как их открывать и закрывать. Получить доступ к файлу данных можно только после его от- крытия. Если файл был закрыт, значит, все данные уже в него записаны.
    Python может создавать буфер и ожидать некоторое время, пока не запишет весь буфер в файл (рис. 2.1). Причина этого проста: доступ к файлам осу- ществляется довольно медленно. Из соображений эффективности Python не записывает биты по отдельности, а ждет, пока буфер наполнится достаточ- ным количеством байтов, после чего сбрасывает весь буфер в файл целиком.
    Рис. 2.1. Открытие и закрытие файла на языке Python
    Именно поэтому рекомендуется с помощью команды f.close()
    закрывать файл после записи в него данных, чтобы гарантировать, что все данные записаны должным образом, а не остались во временной памяти. Однако существует несколько исключений, когда Python закрывает файл автома- тически, в частности, когда счетчик ссылок уменьшается до нуля, как вы увидите в следующем коде.
    Код
    Наша задача: открыть файл, прочитать все строки, удалить ведущие и хво- стовые пробельные символы и сохранить результаты в списке. Соответству- ющий однострочник приведен в листинге 2.3.

    Лямбда-функции и функция map
    1   2   3   4   5   6   7   8   9   ...   21


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