Python

Django, Flask, ORM, инструменты и библиотеки

Локальный LRU-кэш

Разделяемое состояние, если оно обладает признаками изменяемости, должно настоятельно нуждаться в ошибке, такова общепризнанная истина.

— с извинениями к Джейн Остин

Как учили нас г-жа Остин и Хенрик Айхенхардт, разделяемое изменяемое состояние является корнем всего зла. Тем не менее, официальная документация functools предлагает нам писать код наподобие следующего…

Читать дальше

Вычисление расстояния Левенштейна с использованием массивов NumPy

Сколько правок необходимо внести в одно слово, чтобы получить другое? Чем меньше правок нужно сделать, тем выше уровень сходства. В этой статье рассмотрим вариант вычисления расстояния Левенштейна — метрики для измерения разности между двумя строками.

Читать дальше

Как быстро загрузить HTTP-лог Kerio Control размером 6Гб в MariaDB с помощью Python?

В лог-файле HTTP шлюза Kerio Control больше 41 млн строк (формат Apache). Нужно получить возможность применить фильтр по IP, дате или URL. Также было бы здорово извлечь полный список доменов или IP, к которым пользователь обращался в рассматриваемый период времени. SQL удачно подходит для этой задачи.

Читать дальше

Конвейеры в Python

Конвейер позволяет передавать результат выполнения выражения первым параметром в другое выражение. Хорошо знаком системным администратором — помогает передать вывод предыдущей команды на ввод следующей или на вход командного интерпретатора. В Python конвейеры реализуются довольно сложно и вообще поощряется более императивный подход с промежуточными переменными. Но есть интересные эксперименты на эту тему.

Читать дальше

Pandas: построение сводной таблицы с подытогами на каждом уровне мультииндекса

Рассмотрим следующий дейта-фрейм:

a       b       c      Sce1     Sce2    Sce3    Sce4    Sce5    Sc6
Animal  Ground  Dog    0.0      0.9     0.5     0.0     0.3     0.4  
Animal  Ground  Cat    0.6      0.5     0.3     0.5     1.0     0.2 
Animal  Air     Eagle  1.0      0.1     0.1     0.6     0.9     0.1 
Animal  Air     Owl    0.3      0.1     0.5     0.3     0.5     0.9     
Object  Metal   Car    0.3      0.3     0.8     0.6     0.5     0.6 
Object  Metal   Bike   0.5      0.1     0.4     0.7     0.4     0.2 
Object  Wood    Chair  0.9      0.6     0.1     0.9     0.2     0.8 
Object  Wood    Table  0.9      0.6     0.6     0.1     0.9     0.7 

Нужно получить сводный отчет с подытогами:

                     Sce1  Sce2  Sce3  Sce4  Sce5  Sc6
a      b      c                                       
Animal Air    Eagle   1.0   0.1   0.1   0.6   0.9  0.1
              Owl     0.3   0.1   0.5   0.3   0.5  0.9
              Total   1.3   0.2   0.6   0.9   1.4  1.0
       Ground Cat     0.6   0.5   0.3   0.5   1.0  0.2
              Dog     0.0   0.9   0.5   0.0   0.3  0.4
              Total   0.6   1.4   0.8   0.5   1.3  0.6
       Total  Total   1.9   1.6   1.4   1.4   2.7  1.6
Object Metal  Bike    0.5   0.1   0.4   0.7   0.4  0.2
              Car     0.3   0.3   0.8   0.6   0.5  0.6
              Total   0.8   0.4   1.2   1.3   0.9  0.8
       Wood   Chair   0.9   0.6   0.1   0.9   0.2  0.8
              Table   0.9   0.6   0.6   0.1   0.9  0.7
              Total   1.8   1.2   0.7   1.0   1.1  1.5
       Total  Total   2.6   1.6   1.9   2.3   2.0  2.3
Total  Total  Total   4.5   3.2   3.3   3.7   4.7  3.9
Читать дальше

Три вида утечек памяти

Итак, у вас есть программа, которая постепенно использует все больше и больше памяти. Вероятно, вы можете сразу начать рассматривать эту ситуацию как возможный признак утечки памяти. Но когда мы говорим «утечка памяти», что мы на самом деле имеем в виду? По моему опыту, очевидные утечки памяти делятся на три широкие категории, каждая из которых предусматривает разное поведение и предполагает наличие определенных инструментов и подходов для отладки. Этот статья описывает классы утечек и предоставить инструменты и методы для понимания того, с какой категорией вы имеете дело, и как найти утечку.

Читать дальше

О присваивании с использованием среза списка с рекурсивной ссылкой на его копию

В исходниках functools.lru_cache можно встретить следующий кусочек кода:

root = []  # root of the circular doubly linked list
root[:] = [root, root, None, None]  # initialize by pointing to self

Что происходит в этой ситуации? Есть ли какой-то другой синтаксис для достижения того же результата?

Читать дальше

Суммирование элементов списка с накоплением на основе списка индексов

Исходный список:

list_a = [100, 5, 1, 2, 200, 3, 1, 300, 6, 6]

Список индексов:

ind_list = [0, 4, 7]

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

res_list = [100, 105, 106, 108, 200, 203, 204, 300, 306, 312]
Читать дальше

О слиянии нескольких декораторов с аргументами в один

Предположим, есть пара декораторов из разных библиотек: @decorator1(param1, param2) и @decorator2(param3, param4). Декораторы часто использутся в паре:

from moduleA import decorator1
from moduleB import decorator2

@decorator2(foo='param3', bar='param4')
@decorator1(name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
    ...

Хотелось бы иметь декоратор, объединяющий два предыдущих:

@mycustomdecorator(name='param1', state='param2',
                   foo='param3', bar='param4')
def myfunc(funcpar1, funcpar2):
    ...

Как сделать такой декоратор? И стоит ли игра свеч?

Читать дальше

Как Python осуществляет поиск элементов в списке со сложностью O(1)?

li = ["perry", 1, 23.5, "s"]

Элементы этого списка имеют разные размеры в памяти, поэтому нельзя получить доступ к li[3], просто добавив к li[0] размер, трижды превышающий размер каждого элемента. Как интерпретатор понимает, что для доступа к li[3] не нужно проходиться по списку?

Читать дальше

Python 3.8: почему в конструкции with… as не стоит as заменять оператором присваивания?

Теперь, когда PEP 572 принят, в Python 3.8 можно использовать выражения присваивания:

with f := open('file.txt'):
    for l in f:
        print(f)

вместо:

with open('file.txt') as f:
    for l in f:
        print(f)

Эти кусочки кода будут работать одинаково? В чем особенность ключевого слова as в инструкции with ... as в Python 3.8? Не противоречит ли она дзену Python: «Должен существовать один — и желательно только один — очевидный способ сделать это»?

Читать дальше

Почему int в NumPy не является экземпляром Python int, а NumPy float — экземпляр Python float?

>>> import numbers
>>> import numpy
>>> a = numpy.int_(0)
>>> isinstance(a, int)
False
>>> isinstance(a, numbers.Integral)
True
>>> b = numpy.float_(0)
>>> isinstance(b, float)
True
>>> isinstance(b, numbers.Real)
True

Типы numpy.int_ и numpy.float_ находятся в иерархии абстрактного базового класса Python, но объект np.int_ не является экземпляром встроенного класса int, хотя объект np.float_ относится к экземпляру встроенного типа float. Чем объясняется это явление?

Читать дальше

Как определить, содержит ли один список другой?

Вот, например, несколько списков:

>>> l1 = [2, 2, 3]
>>> l2 = [2, 2]
>>> l3 = [3, 2]
>>> l4 = [2, 2, 2]
>>> l5 = [2, 5, 2]

Как определить, входит ли l1 в l2, если в списках есть дубликаты и порядок элементов не важен? Рассматриваем решение с использованием collections.Counter.

Читать дальше

Почему при использовании keyfunc в вызове heapq.nlargest резко падает производительность?

Интересная ситуация:

>>> from random import random
>>> from heapq import nlargest
>>> data = [random() for _ in range(1234567)]
>>> %timeit nlargest(10, data)
30.2 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit nlargest(10, data, key=lambda n: n)
159 ms ± 6.32 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Казалось бы, выполнение может замедлиться примерно на 30%, но не на 400% же. Почему производительность снижается, если передается ключевая функция? Для сравнения: sorted замедляется примерно на 30% с теми же исходными данными и keyfunc.

Читать дальше

Есть ли разница между типами, созданными с помощью namedtuple и NamedTuple?

Сравниваем типы, созданные с использованием typing.NamedTuple и collections.namedtuple. Хотя получившийся код будет работать во всех случаях одинаково, есть несколько нюансов, о которых стоит знать.

Читать дальше