Share This
Связаться со мной
Крути в низ
Categories
//Некоторые специальные возможности Python

Некоторые специальные возможности Python

21.12.2021Category : Python

Python — потрясающий язык программирования! Это один из самых популярных языков для разработки приложений искусственного интеллекта и машинного обучения. Обладая очень простым для изучения синтаксисом, Python имеет некоторые особенности, которые отличают его от других языков. И в этом руководстве мы как раз поговорим об этих особых атрибутах языка программирования Python.

Прочитав данное руководство, вы узнаете:

  • что собой представляют представления списков и словарей;
  • как использовать функции zip() и enumerate();
  • что такое контекст функции и декораторы;
  • для чего нужны генераторы в Python;

Итак, приступим!

Оглавление

Данное руководство разбито на четыре части. Вот они:

  1. Представление списков
  2. Представление словарей
  3. Функции zip() и enumerate()
  4. Контекст функций
  5. Декораторы
  6. Генераторы Pyhon с примерами из библиотеки Keras

Импорт необходимых модулей

Ниже приведен код для импорта необходимых нам библиотек.

from tensorflow import keras from tensorflow.keras.preprocessing.image import ImageDataGenerator import numpy as np import matplotlib.pyplot as plt import math

Представление списков

Синтаксис представления списков обеспечивает простой и надежный способ для создания новых списков из уже существующих. Допустим, нам нужен новый список, в котором каждый элемент старого списка будет умножен на 3. При помощи цикла for мы можем это сделать следующим образом:

original_list = [1, 2, 3, 4] times3_list = []   for i in original_list:     times3_list.append(i*3) print(times3_list)

Результат:

[3, 6, 9, 12]

Более короткий метод, использующий представление списков, укладывается в одну строчку кода:

time3_list_awesome_method = [i*3 for i in original_list] print(time3_list_awesome_method)

Результат:

[3, 6, 9, 12]

Таким образом вы даже можете создать список, отвечающий определенным условиям. Предположим, мы хотим добавлять в новый список только четные числа.

even_list_awesome_method = [i for i in original_list if i%2==0] print(even_list_awesome_method)

Результат:

[2, 4]

Также в подобной конструкции можно использовать ключевое слово else. Допустим, мы хотим оставить четные числа как есть, а нечетные заменить нулями.

new_list_awesome_method = [i if i%2==0 else 0 for i in original_list] print(new_list_awesome_method)

Результат:

[0, 2, 0, 4]

nekotorye specialnye vozmozhnosti python a6ef9c3 - Некоторые специальные возможности Python

Марк Лутц «Изучаем Python»

Скачивайте книгу у нас в телеграм

Скачать ×

С помощью представления списков также можно заменить вложенные циклы for. Рассмотрим следующий пример:

colors = ["red", "green", "blue"] animals = ["cat", "dog", "bird"] newlist = [] for c in colors:     for a in animals:         newlist.append(c + " " + a) print(newlist)

Результат:

['red cat', 'red dog', 'red bird', 'green cat', 'green dog', 'green bird', 'blue cat', 'blue dog', 'blue bird']

Тот же результат может быть достигнут при помощи представления списков:

colors = ["red", "green", "blue"] animals = ["cat", "dog", "bird"]   newlist = [c+" "+a for c in colors for a in animals] print(newlist)

Синтаксис

Синтаксис для представления списков имеет следующий вид:

newlist = [expression for item in iterable if condition == True]

или:

newList = [expression if condition == True else expression for item in iterable]

Представление словарей

Представление словарей похоже на представление списков за исключением того, что в качестве элементов у нас теперь пары ключ-значение. Рассмотрим пример. Мы изменим каждое значение словаря, объединив его со строкой «number«.

original_dict = {1: 'one', 2: 'two', 3: 'three', 4: 'four'} new_dict = {key:'number ' + value for (key, value) in original_dict.items()} print(new_dict)

Результат:

Output {1: 'number one', 2: 'number two', 3: 'number three', 4: 'number four'}

И опять же возможны условные выражения. Мы можем добавлять пары ключ-значения в новый словарь на основании определенных критериев.

#Only add keys which are greater than 2 new_dict_high_keys = {key:'number ' + value for (key, value) in original_dict.items() if key>2} print(new_dict_high_keys)   # Only change values with key>2 new_dict_2 = {key:('number ' + value if key>2 else value) for (key, value) in original_dict.items() } print(new_dict_2)

Результат:

{3: 'number three', 4: 'number four'} {1: 'one', 2: 'two', 3: 'number three', 4: 'number four'}

Функции zip() и enumerate() в Python

В Python итерируемый объект определяется как любая структура данных, способная возвращать все свои элементы по одному. То есть вы можете использовать цикл for для дальнейшей обработки всех элементов один за другим. В Python есть две дополнительные конструкции, которые упрощают использование циклов for. Это функции enumerate() и zip().

От редакции Pythonist. По теме итерируемых объектов и их перебора рекомендуем почитать статью «Встроенные функции для перебора последовательностей в Python».

Enumerate

В традиционных языках программирования вам нужна переменная цикла для перебора различных значений контейнера. В Python это упростили: вы можете получить доступ к переменной цикла вместе со значением итерируемого объекта. Функция enumerate(x) возвращает две итерируемые переменные. Одна из них изменяется в диапазоне от 0 до len(x) – 1, а другая представляет собой элементы x. 

Пример ее использования enumerate():

name = ['Triangle', 'Square', 'Hexagon', 'Pentagon']   # enumerate returns two iterables for i, n in enumerate(name):     print(i, 'name: ', n)

Результат:

0 name:  Triangle 1 name:  Square 2 name:  Hexagon 3 name:  Pentagon

По умолчанию функция enumerate стартует со значения 0, но мы можем задать и другое начальное значение. Иногда это может быть удобным:

data = [1,4,1,5,9,2,6,5,3,5,8,9,7,9,3] for n, digit in enumerate(data[5:], 6):     print("The %d-th digit is %d" % (n, digit))

Результат:

The 6-th digit is 2 The 7-th digit is 6 The 8-th digit is 5 The 9-th digit is 3 The 10-th digit is 5 The 11-th digit is 8 The 12-th digit is 9 The 13-th digit is 7 The 14-th digit is 9 The 15-th digit is 3

Zip

Функция zip() позволяет создавать итерируемый объект, состоящий из кортежей. Zip принимает в качестве аргумента несколько последовательностей (m1, m2,…, mn), в результате чего создается итерируемый объект, состоящий из i кортежей. В каждом кортеже содержится по одному элементу из каждого контейнера. Таким образом, i-й кортеж представляет собой(m1i, m2i,…, mni).

Если переданные объекты имеют разную длину, тогда длина сформированного итерируемого объекта (т.е. количество кортежей) будет равна длине минимального объекта.

От редакции Pythonist. Подробнее о функции zip() и ее применении можно почитать в статье «Используем zip() для парной итерации».

Ниже дан пример совместного применения функций zip() и enumerate().

sides = [3, 4, 6, 5] colors = ['red', 'green', 'yellow', 'blue'] shapes = zip(name, sides, colors)   # Tuples are created from one item from each list print(set(shapes))   # Easy to use enumerate and zip together for iterating through multiple lists in one go for i, (n, s, c) in enumerate(zip(name, sides, colors)):     print(i, 'Shape- ', n, '; Sides ', s)

Результат:

{('Triangle', 3, 'red'), ('Square', 4, 'green'), ('Hexagon', 6, 'yellow'), ('Pentagon', 5, 'blue')} 0 Shape-  Triangle ; Sides  3 1 Shape-  Square ; Sides  4 2 Shape-  Hexagon ; Sides  6 3 Shape-  Pentagon ; Sides  5

Контекст функций

Язык Python допускает применение вложенных функций, в которых вы можете определить внутреннюю функцию внутри внешней. В Python есть несколько замечательных свойств, связанных со вложенными функциями.

  • Внешняя функция может возвращать дескриптор внутренней функции
  • Внутренняя функция сохраняет все свое окружение и переменные, локальные для нее и для внешней функции, даже если внешняя функция завершает свое выполнение.

Ниже дан пример применения этих возможностей.

def circle(r):     area = 0     def area_obj():         nonlocal area         area = math.pi * r * r         print("area_obj")     return area_obj       def circle(r):     area_val = math.pi * r * r     def area():         print(area_val)     return area       # returns area_obj(). The value of r passed is retained circle_1 = circle(1) circle_2 = circle(2)   # Calling area_obj() with radius = 1 circle_1() # Calling area_obj() with radius = 2 circle_2()

Результат:

3.141592653589793 12.566370614359172

Декораторы в Python

Декораторы — мощный инструмент в Python. Вы можете их использовать для тонкой настройки работы класса или функции. Декораторы можно считать функцией, которая применена к другой функции. Чтобы определить функцию-декоратор для декорируемой функции, используется знак @ и после него название функции. Из этого следует, что декоратор принимает в качестве аргумента функцию, которою он декорирует.

Рассмотрим функцию square_decorator(), которая в качестве аргумента принимает функцию и в результате также выдают функцию.

  • Внутренняя вложенная функция square_it() принимает аргумент arg.
  • Функция square_it() применяет функцию к arg и возводит результат в квадрат.
  • Мы можем передать функцию, например sin, в функцию square_decorator(), которая, в свою очередь, вернет sin⁡2(x).
  • Вы также можете написать свою собственную настраиваемую функцию и применить для нее функцию square_decorator() в качестве декоратора, используя для этого специальный символ @, как показано ниже. Функция plus_one(x) возвращает x + 1. Эта функция декорирована функцией square_decorator() и, следовательно, мы получаем (x + 1)2.
def square_decorator(function):     def square_it(arg):         x = function(arg)         return x*x     return square_it   size_sq = square_decorator(len) print(size_sq([1,2,3]))   sin_sq = square_decorator(math.sin) print(sin_sq(math.pi/4))   @square_decorator def plus_one(a):     return a+1   a = plus_one(3) print(a)

Результат:

9 0.4999999999999999 16

Генераторы в Python

Генераторы в Python позволяют создавать последовательности. Вместо выражения return генераторы возвращают значения путем многократного применения выражения yield. При каждом новом вызове функции возвращается следующее значение итерируемой последовательности.

Генератор может быть вызван через функцию next(). При каждом вызове next() возвращается следующее значение генератора. Ниже приведен пример создания последовательности Фибоначчи до числа x.

def get_fibonacci(x):     x0 = 0     x1 = 1     for i in range(x):         yield x0         temp = x0 + x1         x0 = x1         x1 = temp     f = get_fibonacci(6) for i in range(6):     print(next(f))

Результат:

0 1 1 2 3 5

Пример генератора данных из библиотеки Keras

Одно из типичных применений генераторов — это использование генератора данных в библиотеке Keras. Причина, по которой он полезен, заключается в том, что мы не хотим хранить все данные в памяти, а хотим создавать их на лету, когда это необходимо в процессе обучения. Дело в том, что в Keras модель нейронной сети обучается батчами, поэтому генератор должен выдавать строго определенные пакеты данных.

def datagen(data, seq_len, batch_size, targetcol, kind):     "As a generator to produce samples for Keras model"     batch = []     while True:         # Pick one dataframe from the pool         key = random.choice(list(data.keys()))         df = data[key]         input_cols = [c for c in df.columns if c != targetcol]         index = df.index[df.index < TRAIN_TEST_CUTOFF]         split = int(len(index) * TRAIN_VALID_RATIO)         if kind == 'train':             index = index[:split]   # range for the training set         elif kind == 'valid':             index = index[split:]   # range for the validation set         # Pick one position, then clip a sequence length         while True:             t = random.choice(index)      # pick one time step             n = (df.index == t).argmax()  # find its position in the dataframe             if n-seq_len+1 < 0:                 continue # can't get enough data for one sequence length             frame = df.iloc[n-seq_len+1:n+1]             batch.append([frame[input_cols].values, df.loc[t, targetcol]])             break         # if we get enough for a batch, dispatch         if len(batch) == batch_size:             X, y = zip(*batch)             X, y = np.expand_dims(np.array(X), 3), np.array(y)             yield X, y             batch = []

Данная функция берет случайную строку из датафрейма pandas и вырезает несколько следующих за ней строк в качестве выборки временного интервала. Этот процесс повторяется несколько раз, чтобы собрать достаточно временных интервалов для батча. Когда мы собрали достаточно данных, пакет отправляется на обучение при помощи выражения yield. Как вы уже заметили, в генераторах нет выражения return и в данном примере эта функция будет работать все время. Это полезно и удобно, потому что позволяет нашему процессу обучения проходить любое количество эпох.

Без генератора нам постоянно приходилось бы конвертировать наш датафрейм и хранить в памяти все возможные интервалы времени в процессе всего цикла обучения. Это даст нам весьма много повторяющихся данных (так как временные интервалы пересекаются) и займет очень много памяти.

Именно поэтому в Keras уже есть предопределенная функция генератора. Ниже приведен пример использования функции ImageDataGenerator().

Мы загрузили набор данных cifar10 с изображениями 32×32 в переменную x_train. Данные подключаются к генератору через метод flow(). Функция next() возвращает следующий батч данных. В приведенном ниже примере есть четыре вызова функции next(). В каждом случае возвращается 8 изображений, так как размер батча равен 8.

Ниже приведен код, который отображает все картинки после каждого вызова функции next().

(x_train, y_train), _ = keras.datasets.cifar10.load_data() datagen = ImageDataGenerator() data_iterator = datagen.flow(x_train, y_train, batch_size=8)   fig,ax = plt.subplots(nrows=4, ncols=8,figsize=(18,6),subplot_kw=dict(xticks=[], yticks=[]))   for i in range(4):     # The next() function will load 8 images from CIFAR     X, Y = data_iterator.next()     for j, img in enumerate(X):         ax[i, j].imshow(img.astype('int'))

Результат:

nekotorye specialnye vozmozhnosti python 373942e - Некоторые специальные возможности Python

Дальнейшее обучение

Документация Python

  • Python Documentation at python.org

Книги

  • Think Python: How to Think Like a Computer Scientist by Allen B. Downey
  • Programming in Python 3: A Complete Introduction to the Python Language by Mark Summerfield
  • Python Programming: An Introduction to Computer Science by John Zelle

Справочник API

  • Keras ImageDataGenerator

Заключение

В этом руководстве вы открыли для себя некоторые специальные возможности языка Python.

А именно, мы изучили:

  • назначение представления списков и словарей;
  • как использовать функции zip() и enumerate();
  • вложенные функции, контекст функций и декораторы;
  • генераторы в Python и ImageDataGenerator в библиотеке Keras;

Перевод статьи Mehreen Saeed «More special features in Python«.

nekotorye specialnye vozmozhnosti python f37ff8a - Некоторые специальные возможности Python

Марк Лутц «Изучаем Python»

Скачивайте книгу у нас в телеграм

Скачать ×

  • 1 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2022 / All rights reserved

    Связаться со мной
    Close