вторник, 18 сентября 2018 г.

Генераторы и итераторы (экстракт из М.Лутца)


Марк Лутц неоднократно писал о важности понимания генераторов и итераторов. Здесь я коротко изложу основные положения из важной главы № 20 книги "Изучаем python".




Отображение операций на последовательности и сбор результатов - очень частая задача. Можно это делать через:

  1. цикл for; 
  2. функциональное программирование (например функция map); 
  3. разовую функцию lambda. 
  4. Но лучше всего через генератор списка. Пример:
res = [ord(x) for x in 'spam']
res
[115,112,97,109]

В отличие от функции map генератор отображает выражение на последовательность и сразу выдаёт весь результат. Он гибкий (можно сделать вложенные циклы, можно обрабатывать вложенные списки т.е. матрицы) и быстрее всех аналогов.


Но может понадобится получать не все результаты сразу, а по требованию. Это возможно реализовать двумя способами.

Функция генератор и инструкция yield (глагол переводится как 'уступать').

Обычная функция возвращает всю последовательность сразу, после чего завершает работу. 
Функция-генератор приостанавливает и возобновляет выполнение работы, воспроизводя последовательность значений. При вызове возвращается объект генератора. 

def createGenerator():
    mylist = range(3)
    for i in mylist:
        yield i*i                                          # yield вместо return, т.е. замораживание  состояния

mygenerator = createGenerator()                                   # создать генератор
print(mygenerator)                                  
<generator object createGenerator at 0xb7555c34>      # выдаёт объект
for i in mygenerator:                                                       # итерируем объект но только 1 раз!
    print(i)
0
1
4

В 3-й версии языка появилась новая конструкция - выражение-генератор. Внешне похоже на генератор списков, но в круглых скобках. Возвращает объект-генератор, который поддерживает протокол итераций, возвращая по одному элементу списка за раз. Но тоже - можно его проитерировать только однократно.

 g = (x ** 2 for i in range(4))
 next(g)
0
 next(g)
1
 next(g)
2
 next(g)
3
 next(g)
StopIteration


Также в 3й версии языка добавились генераторы множеств и словарей. Они как генераторы списков - возвращают всю последовательность сразу.
Генератор множеств:
    {x*x for x in range(5)}
{0,1,4,9,16}
Генератор словаря:
    {x:x*x for x in range(5)}
{0:0, 1:1, 2:4, 3:9, 4:16}


понедельник, 17 сентября 2018 г.

from 'Nuances of programming'

Телеграм канал Nuances of programming иногда переводит статьи про python. Сенсационного там ничего нет, но бывают забавные факты. Вот очередные 'Полезные хитрости', из которых я вытянул несколько пунктов.

https://awesome-python.com/ 

не знал про такой сайт, действительно интересно

bashplotlib

Графики в консоли. Забавно, но по моему бессмысленно.

emoji
Эмодзи. То же самое, в смысле бессмысленно, есть документация.

geopy, dictance
Абстрагированиe API-интерфейсов различных сервисов геокодирования, что позволяет вам получать доступ к полному адресу нужного места, его широте, долготе и даже высоте. ..... Не вполне понимаю, но явно не скоро понадобится.

howdoi
Пишется в консоли вопрос (howdoi undo commits in git) а он выдирает ответ со стекоферфлоу, берёт оттуда самый популярный ответ. Не хочу показаться грубым, но это тоже скорее "курьёзы'

inspect, jedi
Понимание кода. Заодно скажу очередное спасибо Марку Лутцу, на этот раз за прекрасный термин 'интроспекция'.

newspaper3k
" ... может доставать новостные статьи и связанные с ними мета-данные из ряда ведущих международных изданий. Извлекать можно картинки, текст и имена авторов..." . Вот это прямо заинтересовало. Потестирую и расскажу.

sh
Минискриптовый язык, можно вызывать любую программу как обычную функцию . Альтернативы bash'у, смысла не вижу.

uuid
Универсальные Уникальные Идентификаторы. Видимо, что-то типа хеш-номера.

wikipedia
Доступ к API сайта.

xkcd
Шутки юмора от Монти Пайтона

yaml
Язык форматирования данных, расширенная версия json