В Python извлечение последнего элемента из списка занимает постоян-
ное время, но извлечение первого элемента является линейным по длине списка. В худшем случае
длина стека составляет O(n), что делает эту реализацию поиска в ширину O(nm), что намного хуже,
чем должно быть, O(n + m).
from collections import deque - позволяет использовать очередь, которая использует линейное время для доступа к элементам с обоих сторон
ное время, но извлечение первого элемента является линейным по длине списка. В худшем случае
длина стека составляет O(n), что делает эту реализацию поиска в ширину O(nm), что намного хуже,
чем должно быть, O(n + m).
from collections import deque - позволяет использовать очередь, которая использует линейное время для доступа к элементам с обоих сторон
collections.counter
words = [Малоизвестная возможность экземпляров Counter состоит в том, что они могут быть легко скомбинированы с использованием разнообразных математических операций. Например:
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
]
from collections import Counter
word_counts = Counter(words)
top_three = word_counts.most_common(3)
print(top_three)
# Выведет [('eyes', 8), ('the', 5), ('look', 4)]
>>> a = Counter(words)#algoritms #collections #counter
>>> b = Counter(morewords)
>>> a
Counter({'eyes': 8, 'the': 5, 'look': 4, 'into': 3, 'my': 3, 'around': 2,
"you're": 1, "don't": 1, 'under': 1, 'not': 1})
>>> b
Counter({'eyes': 1, 'looking': 1, 'are': 1, 'in': 1, 'not': 1, 'you': 1,
'my': 1, 'why': 1})
>>> # Объединяем счетчики
>>> c = a + b
>>> c
Counter({'eyes': 9, 'the': 5, 'look': 4, 'my': 4, 'into': 3, 'not': 2,
'around': 2, "you're": 1, "don't": 1, 'in': 1, 'why': 1,
'looking': 1, 'are': 1, 'under': 1, 'you': 1})
>>> # Вычитаем счетчики
>>> d = a - b
>>> d
Counter({'eyes': 7, 'the': 5, 'look': 4, 'into': 3, 'my': 2, 'around': 2,
"you're": 1, "don't": 1, 'under': 1})
>>>
Сортировка списка словарей по общему ключу
полей, общих для всех словарей. Например:
#algoritms #sorting #operator #itemgetter #attgetter
rows = [Можно достаточно легко вывести эти строки с упорядочением по любому из
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
полей, общих для всех словарей. Например:
from operator import itemgetterаналогично:
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_uid)
>>>
[{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}]
rows_by_fname = sorted(rows, key=lambda r: r['fname'])но itemgetter работает быстрее. operator.attgetter() работает с аттрибутами обьектов
#algoritms #sorting #operator #itemgetter #attgetter
Группирование записей на основе полей
Функция itertools.groupby()
Функция itertools.groupby()
rows = [#algoritms #itertools #groupby
{'address': 'CLARK', 'date': '07/01/2012'},
{'address': 'CLARK', 'date': '07/04/2012'},
{'address': '58TH', 'date': '07/02/2012'},
{'address': 'CLARK', 'date': '07/03/2012'},
{'address': 'RAVENSWOOD', 'date': '07/02/2012'},
{'address': 'ADDISON', 'date': '07/02/2012'},
{'address': 'BROADWAY', 'date': '07/01/2012'},
{'address': 'GRANVILLE', 'date': '07/04/2012'},
]
from operator import itemgetter
from itertools import groupby
# Сначала сортируем по нужным полям
rows.sort(key=itemgetter('date'))
# Итерируем в группах
for date, items in groupby(rows, key=itemgetter('date')):
print(date)
for i in items:
print(' ', i)
>>>
07/01/2012
{'date': '07/01/2012', 'address': 'CLARK'}
{'date': '07/01/2012', 'address': 'BROADWAY'}
07/02/2012
{'date': '07/02/2012', 'address': '58TH'}
{'date': '07/02/2012', 'address': 'RAVENSWOOD'}
{'date': '07/02/2012', 'address': 'ADDISON'}
07/03/2012
{'date': '07/03/2012', 'address': 'CLARK'}
07/04/2012
{'date': '07/04/2012', 'address': 'CLARK'}
{'date': '07/04/2012', 'address': 'GRANVILLE'}
Удаление дубликатов из последовательности
с сохранением порядка элементов
#algoritms #generators
с сохранением порядка элементов
def dedupe(items):Множество не сохраняет какой бы то ни было порядок, поэтому результат будет перемешан.
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)
#algoritms #generators
оператор nonlocal. from python 3+
Логика его написания примерно такая же, как и у global. Однако у nonlocal есть особенность. Nonlocal используется чаще всего во вложенных функциях, когда мы хотим дать интерпретатору понять, что для вложенной функции определенная переменная не является локальной, но она и не является глобальной в общем смысле.
Логика его написания примерно такая же, как и у global. Однако у nonlocal есть особенность. Nonlocal используется чаще всего во вложенных функциях, когда мы хотим дать интерпретатору понять, что для вложенной функции определенная переменная не является локальной, но она и не является глобальной в общем смысле.
def get_candy():#operator #nonlocal
candy = 5
def increment_candy():
nonlocal candy
candy += 1
return candy
return increment_candy
result = get_candy()()
print('Всего {} конфет.'.format(result))
>>>
Всего 6 конфет.
Реализация цикла for с помощью функции и цикла while
#algoritms #iterator #exceptions
def for_loop(iterable, loop_body_func):Здесь использовали конструкцию try-else. Она позволяет выполнять код, если исключения не возникло, и код был выполнен успешно.
iterator = iter(iterable)
next_element_exist = True
while next_element_exist:
try:
element_from_iterator = next(iterator)
except StopIteration:
next_element_exist = False
else:
loop_body_func(element_from_iterator)
#algoritms #iterator #exceptions
* Итерируемый объект — это что-то, что можно итерировать.
* Итератор — это сущность порождаемая функцией iter, с помощью которой происходит итерирование итерируемого объекта.
* Итератор не имеет индексов и может быть использован только один раз.
* Итератор имеет методы __next__ __iter__, а также вызывает исключение StopIteration при невозможности получения следующего элемента
* В случае, если мы передаём в iter итератор, то получаем тот же самый итератор
* Итератор — это сущность порождаемая функцией iter, с помощью которой происходит итерирование итерируемого объекта.
* Итератор не имеет индексов и может быть использован только один раз.
* Итератор имеет методы __next__ __iter__, а также вызывает исключение StopIteration при невозможности получения следующего элемента
* В случае, если мы передаём в iter итератор, то получаем тот же самый итератор
class InfiniteSquaring:#iterrator #iter #next
"""Класс обеспечивает бесконечное последовательное возведение в квадрат заданного числа."""
def __init__(self, initial_number):
# Здесь хранится промежуточное значение
self.number_to_square = initial_number
def __next__(self):
# Здесь мы обновляем значение и возвращаем результат
self.number_to_square = self.number_to_square ** 2
return self.number_to_square
def __iter__(self):
"""Этот метод позволяет при передаче объекта функции iter возвращать самого себя, тем самым в точности реализуя протокол итератора."""
return self
Кэширование (мемоизация) с помощью lru_cache
import functools#lru_cache #decorator
import time
# кэширование до 12 различных результатов
@functools.lru_cache(maxsize=12)
def slow_func(x):
time.sleep(2) # Имитируем длительные вычисления
return x
slow_func(1) # ... ждём 2 секунды до возврата результата
slow_func(1) # результат уже кэширован - он возвращается немедленно!
slow_func(3) # ... опять ждём 2 секунды до возврата результата
https://arpitbhayani.me/blogs/fsm - примеры взаимодействия последовательных процессов на python
#fsm #asyncio
#fsm #asyncio
arpitbhayani.me
Building Finite State Machines with Python Coroutines
The most intuitive way of building and implementing Finite State Machines is by using Python Coroutines and in this article, we find how and why.
https://www.artificialworlds.net/blog/2017/06/12/making-100-million-requests-with-python-aiohttp/ - хороший пример по использованию aiohttp
#aiohttp
#aiohttp
https://medium.com/@yeraydiazdiaz/asyncio-coroutine-patterns-errors-and-cancellation-3bb422e961ff - пример по обработке ошибок и логгированию с asyncio
#asyncio #exceptions #logging
#asyncio #exceptions #logging
Medium
Asyncio Coroutine Patterns: Errors and cancellation
This is the second part of a two part series on coroutine patterns in asyncio, to fully benefit from this article please read the first…
Никогда не стоит использовать f-strings для логгирования в python, такие строки будут выполняться вне зависимости от того, должна ли быть вызвана функция логгирования на текущем уровне. Стоит использовать старый формат для строк.
logger.info('Requests sent: %s success: %s errors: %s', self.request_sent, self.success, self.errors)
#logging #f_strings