Показаны сообщения с ярлыком ЛМНты. Показать все сообщения
Показаны сообщения с ярлыком ЛМНты. Показать все сообщения

суббота, 2 января 2021 г.

ЛМНты Python, 96 - 100

>>> Декартово произведение

Декартово произведение последовательностей или множеств можно получить с помощью спискового включения или множественного включения. Например:

>>> [(x, y) for x in (1, 2) for y in (-2, -1)]
[(1, -2), (1, -1), (2, -2), (2, -1)]
>>>
>>> {(x, y) for x in {1, 2} for y in {-2, -1}}
{(1, -1), (2, -2), (1, -2), (2, -1)}

В модуле itertools имеется функция product для получения декартовых произведений. Получим тот же результат с ее помощью.

вторник, 1 декабря 2020 г.

ЛМНты Python, 91 - 95

>>> Две или больше, the Python way

Чтобы перебрать все элементы последовательности, делается цикл по элементам последовательности:

>>> letters = ['a', 'b', 'c']
>>> for x in letters:
...     pass
...

Если нужно параллельно перебирать элементы нескольких последовательностей, то прибегают к индексированию:

>>> numbers = [1, 2, 3]
>>> for i in range(len(letters)):
...     letter = letters[i]
...     number = numbers[i]
...

воскресенье, 1 ноября 2020 г.

ЛМНты Python, 86 - 90

>>> Стиль имеет значение

PEP8 – это руководство по стилю кодирования на Python. PEP8 рекомендует, чтобы имена функций и переменных использовали буквы только в нижнем регистре и _ (подчеркивание) в качестве разделителя слов:

i
name
full_name

Использование однобуквенных переменных l (эл), O (оу) и I (ай) считается злом, так как их непросто отличить от цифр 1 и 0 или друг от друга (l и I).

суббота, 10 октября 2020 г.

ЛМНты Python, 81 - 85

>>> Глубина копирования

Метод copy выполняет поверхностное копирование, связывая атрибуты объекта-копии с теми же объектами, с которыми связаны атрибуты объекта-оригинала. Иными словами, объекты, на которые ссылаются атрибуты копируемого объекта, не копируются:

>>> a = [
...     [1, 2, 3],
...     [4, 5, 6]
... ]
>>>
>>> b = a.copy()
>>> b[1][0] = -4
>>> b[1][1] = -5
>>> b[1][2] = -6
>>>
>>> b
[[1, 2, 3], [-4, -5, -6]]
>>> a
[[1, 2, 3], [-4, -5, -6]]
>>>
>>> a[1] is b[1]
True

вторник, 1 сентября 2020 г.

ЛМНты Python, 76 - 80

>>> Разоблачение operator.itemgetter

Боюсь, последний пример с функцикй itemgetter непонятен или не нагляден.

Функция itemgetter возвращает функцию (точнее, callable объект), которая принимает на вход последовательность и возвращает элемент последовательности с нужным индексом:

>>> from operator import itemgetter
>>>
>>> getitem2 = itemgetter(2)
>>> getitem2(['a','b','c'])
'c'
>>> itemgetter(0)(['a','b','c'])
'a'
>>> itemgetter(1)(['a','b','c'])
'b'

суббота, 1 августа 2020 г.

ЛМНты Python, 71 - 75

>>> Ваша правда

В отлиичие от пустых объектов стандартных классов, объект вашего класса по умолчанию оценивается как True:

>>> class B(object):
...     pass
...
>>> b = B()
>>> if b:
...     print('True')
...
True
>>> bool(b)
True

Для того, чтобы ваш объект был оценен как False, его метод __len__ должен возвращать 0 или метод __bool__ – возвращать False.

среда, 1 июля 2020 г.

ЛМНты Python, 66 - 70

>>> Ещё множества могут

С помощью расширенных операторов присваивания (или соответствующих им методов) можно присваивать левому множеству результат операции над ним и правым множеством:

>>> a, b = ({1, 2, 3}, {3, 4, 5})
>>> # объединение
... a |= b
>>> a.update(b)
>>> a
{1, 2, 3, 4, 5}
>>>
>>> a, b = ({1, 2, 3}, {3, 4, 5})
>>> # пересечение
... a &= b
>>> a.intersection_update(b)
>>> a
{3}
>>>
>>> a, b = ({1, 2, 3}, {3, 4, 5})
>>> # разность
... a -= b
>>> a.difference_update(b)
>>> a
{1, 2}
>>>
>>> a, b = ({1, 2, 3}, {3, 4, 5})
>>> # симметрическая разность
... a ^= b
>>> a.symmetric_difference_update(b)
>>> a
{1, 2, 3}

См. также лмнт Множества могут.

вторник, 2 июня 2020 г.

ЛМНты Python, 61 - 65

>>> Декоратор lru_cache

Еще один полезный декоратор из модуля functools стандартной библиотеки Python – это lru_cache(maxsize=128, typed=False). Этот декоратор запоминает до maxsize последних результатов, возвращаемых декорированной функцией для различных аргументов и, в случае повторного обращения к функции с теми же аргументами, возвращает результат из кэша вместо того, чтобы вызывать функцию.

Воспользуемся им, чтобы кэшировать значения чисел Фибоначчи, рассчитанные функцией fibc.

пятница, 1 мая 2020 г.

ЛМНты Python, 56 - 60

>>> Значение параметра по умолчанию

В следующем определении функции параметр c имеет значение по умолчанию:

>>> def fun(a, b, c=True):
...     return a if c else b
...
>>> fun(1, 2)
1
>>> fun(1, 2, 2<1)
2

Значения параметров по умолчанию вычисляются один раз в момент выполнения предложения def. Из этого следует, что

  • в них можно использовать видимые на этот момент имена и
  • они могут изменяться уже после определения функции, если являются изменяемыми (mutable) объектами.

среда, 1 апреля 2020 г.

ЛМНты Python, 51 - 55

>>> Как замыкания

Интересно, что во вложенных функциях используемые нелокальные переменные точно так же доступны через locals(), как это происходит в замыканиях с бесплатными переменными:

>>> def f():
...     one = 1
...     print('f:', locals())
...     def g():
...         two = one + 1
...         print('g:', locals())
...         def h():
...             three = two + 1
...             print('h:', locals())
...         h()
...     g()
...
>>> f()
f: {'one': 1}
g: {'two': 2, 'one': 1}
h: {'three': 3, 'two': 2}

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

воскресенье, 1 марта 2020 г.

ЛМНты Python, 46 - 50

>>> Нелокальное имя

Имя x, созданное операцией присваивания в начале функции fun, внутри вложенной функции fun2 экранируется другим именем x:

>>> def fun():
...     x = 'fun'
...     def fun2():
...         x = 'fun2'
...         print(x)
...     fun2()
...     print(x)
...
>>> fun()
fun2
fun

суббота, 1 февраля 2020 г.

ЛМНты Python, 41 - 45

>>> Генератор

Объект-генератор можно создать не только с помощью генераторного выражения, но и с помощью функции с предложением yield внутри:

>>> def down5():
...     n = 5
...     while n:
...         yield n
...         n -= 1
...
>>> type(down5)
<class 'function'>
>>> d5 = down5()
>>> type(d5)
<class 'generator'>

четверг, 2 января 2020 г.

ЛМНты Python, 36 - 40

>>> Две или больше

Функции map можно подать на вход больше одной последовательности и обработать их параллельно. Например, просуммировать поэлементно две последовательности:

>>> s1 = [1, 2, 3]
>>> s2 = [4, 5, 6, 7]
>>> m = map(lambda x, y: x+y, s1, s2)
>>> list(m)
[5, 7, 9]

Обработка завершается, когда достигнут конец самой короткой последовательности. Так же ведет себя функция zip, собирающая из нескольких последовательностей одну – с кортежами:

>>> z = zip(s1, range(5))
>>> list(z)
[(1, 0), (2, 1), (3, 2)]
>>> m = map(lambda x, y: (x, y), s1, range(5))
>>> list(m)
[(1, 0), (2, 1), (3, 2)]

воскресенье, 1 декабря 2019 г.

ЛМНты Python, 31 - 35

>>> map и filter

Встроенные функции map и filter принимают на вход функцию и последовательность, а возвращают итерируемый объект, порождающий новую последовательность путем вызова полученной функции для каждого элемента входной последовательности.

Функция, передаваемая в map, отображает входное значение на другое. Например:

>>> def cube(n):
...     return n**3
...
>>> m = map(cube, [1, 2, 3, 4])
>>> type(m)
<class 'map'>
>>> list(m)
[1, 8, 27, 64]

суббота, 2 ноября 2019 г.

ЛМНты Python, 26 - 30

>>> Zen of Python

Модуль this хранит принципы программирования на Python, извеcтные как Zen of Python:

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

вторник, 1 октября 2019 г.

ЛМНты Python, 21 - 25

>>> Последовательность из итератора

Последовательность можно задать явно, перечислив ее элементы, или аналитически, передав конструктору итератор, порождающий элементы последовательности. Наверное, самый популярный итератор – тот, что предоставляется объектом класса range, получаемым с помощью функции range().

>>> it = iter(range(5))
>>> type(it)
<class 'range_iterator'>
>>> next(it)
0
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
4
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

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

ЛМНты Python, 16 - 20

>>> Больше, чем гугол

Целое число в Python ограничено только памятью компьютера:

>>> from math import factorial
>>> factorial(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

А число класса float следует стандарту для хранения чисел с плавающей точкой двойной точности. Если преобразовать 100! в число float, а затем обратно в int, это будет уже другое число из-за потери значащих цифр при преобразовании в float:

>>> float(factorial(100))
9.332621544394415e+157
>>> int(float(factorial(100)))
93326215443944150965646704795953882578400970373184098831012889540582227238570431295066113089288327277825849664006524270554535976289719382852181865895959724032

Как видим, неизменными сохранились только старшие 16 десятичных знаков. Кстати, число 100! намного больше знаменитого числа гугол:

>>> factorial(100) > 10**100
True

четверг, 1 августа 2019 г.

ЛМНты Python, 11 - 15

>>> or else

Часто, когда полученное значение пусто, нужно использовать значение по умолчанию, чтобы программа продолжила работу. В этой ситуации можно использовать тернарный оператор:

name = user_name()
name = name if name else 'User'

Но можно написать более компактный код, используя оператор or:

name = user_name() or 'User'

Оператор or работает по короткой схеме (short-sircuit) и возвращает первое же значение, которое оценивается как True. Хотя выражение выглядит как логическое, его результатом является не булево значение!

понедельник, 1 июля 2019 г.

ЛМНты Python, 6 - 10

>>> is [not]

Недавно мы сравнивали id объектов, чтобы показать, что булевы значения True, полученные разными способами, представлены одним и тем же объектом:

>>> id(1 == 1) == id(True)
True
>>> id(bool(1)) == id(not False)
True

Чтобы проверить, что за двумя значениями или именами стоит один и тот же объект, в Python имеется оператор is (который, на самом деле, сравнивает id двух объектов).

суббота, 1 июня 2019 г.

ЛМНты Python, 1 - 5

>>> Выражения – это предложения

Выражения – полноценные предложения языка Python:

python
>>> 3.14
3.14
>>> [1,2] + [3]
[1, 2, 3]
>>> 'Привет, Python'
'Привет, Python'
>>> """Можно написать скрипт из одних выражений,
... и он выполнится без ошибок.
... """
'Можно написать скрипт из одних выражений,\nи он выполнится без ошибок.\n'
>>>

Документирующие строки Python (docstrings) – это выражения, состоящие из строкового литерала, а не особая конструкция, требующая специальной обработки.