Это продвинутая функция списков Python, делающая код более чистым и читабельным. Композиция — это способ выполнения ряда операций над списком с использованием одной строки. Включения обычно обозначаются выражением for в квадратных скобках. Ниже приведен шаблон для спискового включения:
newList = [returned_value for item in list condition_logic ]Списковые включения могут использоваться для извлечения элементов, соответствующих определенным критериям. В следующем примере они используются для извлечения всех четных чисел из списка:
# Создание списка чисел от 0 до 49
numRange = range(0,50)
# Извлечение всех четных чисел
evenNums = [num for num in numRange if num % 2 == 0 ]
В приведенном выше примере мы создаем новый список с num
. Он возвращается из цикла for, в котором остаток (%
по модулю) от num
, разделенного на два, равен нулю.
Списковые включения могут использоваться для выполнения операций над элементами в списке. В следующем примере показано, как все элементы списка могут быть возведены в квадрат:
# Создание списка чисел от 0 до 49
numRange = range(0,50)
# Извлечение всех четных чисел
evenNums = [num * num for num in numRange]
Это один из особенно полезных фрагментов кода, который поможет избежать дорогих вызовов функций.
Мемоизация — это процесс сохранения значений в памяти во избежание повторного пересчитывания результатов.
Процесс выглядит следующим образом: у вас есть список, который может содержать дублирующиеся данные или функцию, которую необходимо запустить, чтобы проверить вывод и вернуть значение. Здесь на помощь приходит мемоизация, использующая словарь для отслеживания результатов вызовов функций с одинаковыми входными параметрами.
def memoize(f):
""" Memoization decorator for functions taking one or more arguments. """
class memodict(dict):
def __init__(self, f):
self.f = f
def __call__(self, *args):
return self[args]
def __missing__(self, key):
ret = self[key] = self.f(*key)
return ret
return memodict(f)
# Инициализация переменной вызова глобальной функции
funcRuns = 0
# Упаковка функции во враппере мемоизации
@memoize
def f(x):
global funcRuns
# Увеличение funcRuns при каждом запуске функции
funcRuns += 1
return True
# Инициализация списка чисел
nums = [0,1,2,3,4,4]
# Запуск спискового включения с двумя вызовами f(x) на каждую итерацию
# с 6 элементами в списке и 2 вызовами за итерацию, что
# приведет к 12 выполнениям функций.
[f(x) for x in nums if f(x)]
# Запуск номера журнала f(x)
print(funcRuns)
При запуске вышеуказанного примена вы обнаружите, что функция запускается только 5 раз, несмотря на то, что в списковом включении два вызова f(x)
, а в списке 6 элементов. На каждый уникальный номер приходится только по одному вызову. В противном случае используется кэшированное значение. При наличии дорогих вызовов функции скорость кода значительно возрастет с помощью мемоизации результатов.
Этот способ отлично подходит для повышения скорости относительно небольших списков. С очень большими списками он может вызвать проблемы при работе, поскольку все вводы/выводы кэшируются, пока функция находится в области видимости, что требует большого количества памяти для хранения значений.
Наряду со списковыми включениями для списков доступны и другие полезные методы.
Метод zip используется для объединения нескольких списков Python в кортежи. Если два списка имеют разную длину, то длинный будет обрезан до длины короткого.
first_names = ['John', 'Jeff', 'Chris']
last_names = ['Wick', 'Chen', 'Test', 'Truncated']
names = zip(first_names, last_names)
for name in names:
print(name)
# Вывод:
('John', 'Wick')
('Jeff', 'Chen')
('Chris', 'Test')
Метод сортировки достаточно редко используется с пользовательскими функциями ранжирования. Ниже приведена сортировочная функция, которая возвращает лучшие статьи за день. В конце также используется списковое включение.
posts = [
{
'Post': {
'title':'Other today post',
'date': 43750,
'claps': 200
}
},
{
'Post': {
'title':'Python Like a Pro - Lists and Their Many Uses',
'date': 43750,
'claps': 525
}
},
{
'Post': {
'title':'Yesterdays news',
'date': 43749,
'claps': 25
}
},
]
# Rank возвращает кортеж дней
# с 1900 года и по количеству лайков
def rank(element):
return (element['Post']['date'],
element['Post']['claps'])
# Сортировка с использованием алгоритма ранжирования
# и замена мест так, чтобы нынешняя дата
# с наибольшим количеством лайков стояла первой
posts.sort(key=rank, reverse=True)
# И, наконец, списковое включение, чтобы связать все вместе
print([post['Post']['title'] for post in posts])
Выводом этого кода будет следующий список, где на первом месте стоит самая свежая и самая популярная статья.
['Python Like a Pro - Lists and Their Many Uses',
'Other today post',
'Yesterdays news']
Перевод статьи David Tippett: Advanced Python List Methods and Techniques — Python Like a Pro
Комментарии