Мы поговорим о некоторых распространенных рецептах структуры данных в Python.

В Python существует множество структур данных, таких как список, кортеж и словарь. Хотя использование этих структур не вызывает затруднений, при использовании некоторых операций сравнения, таких как сортировка, упорядочивание и фильтрация, могут возникнуть общие вопросы. В этой короткой статье мы обсудим некоторые распространенные структуры данных и алгоритмы, связанные с данными. Без лишних слов, давайте перейдем к коду :)

Звездный оператор

Вам нужно распаковать Nколичество переменных из итерации, но длина итерации может быть больше, чем N. Таким образом, мы можем использовать звездочку (*) для решения этой проблемы.

record = ('Math', '[email protected]', '098-111-2345', '946-999-756')
name, email, *phone_numbers = user_record
>>> name
'Math'
>>> email
'[email protected]'
>>> phone_numbers 
['098-111-2345', '946-999-756']
record = ('PTE', 60, 435.45, (03, 24, 2015))
name, *_, (*_, year) = record
>>> name
'PTE'
>>> year
2012

Сохранение последних Nэлементов с использованием очереди

Цель состоит в том, чтобы сохранить ограниченную историю последнего количества элементов во время итерации или других данных обработки. Для этого мы можем использовать deque из библиотеки collections. Хотя вы можете использовать метод list by append, однако deque намного быстрее и эффективнее. Один пример того, как использовать deque, выглядит следующим образом:

q = deque(maxlen=3) 
q.append(1)
q.append(2)
q.append(3)
>>> q
deque([1, 2, 3], maxlen=3)
q.append(4)
>>> q
deque([2, 3, 4], maxlen=3)

Если вы не укажете maxlen,, очередь станет неограниченным хранилищем. Вы можете использовать другие методы для управления очередью. Например, pop, popleft, и appendleft.

Мы можем разработать очередь на основе приоритетов, которая будет представлена ​​позже, используя heapq structure.

Поиск наибольшего и наименьшего из N элементов — heapq

У вас есть список элементов, и вы хотите получить nнаибольшего или наименьшего элемента списка. Мы можем использовать структуру heapq. Структура данных кучи в основном используется для представления приоритетной очереди. Свойство этой структуры данных в Python состоит в том, что каждый раз извлекается наименьший элемент кучи (min heap). Всякий раз, когда элементы помещаются или извлекаются, структура кучи сохраняется. Элемент heap[0] также каждый раз возвращает наименьший элемент.

Два метода heapq, nlargest, и smallestможно использовать для получения n наименьших или наибольших элементов.

import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] 
heapq.nlargest(3, nums) 
>>> [42, 37, 23] 
heapq.nsmallest(3, nums)) 
>>> [-4, 1, 2]
heapq.heappop(heap) 
>>> -4
heapq.heappop(heap)
>>> 1
heapq.heappop(heap) 
>>> 2

Под прикрытием они работают, сначала преобразовывая данные в список, где элементы упорядочены как куча. Таким образом, этот подход обеспечивает превосходную производительность, если n меньше, чем общее количество элементов N.

Реализация очереди на основе приоритетов с использованием heapq

Мы можем использовать ту же структуру для реализации очереди на основе приоритетов, используя класс heapq.

queue = []
# the first element of tuple is priority and the second is the item
heapq.heappush(queue, (-1, 3))
heapq.heappush(queue, (-2, 4))
heapq.heappush(queue, (0, 5))
heapq.heappop(queue)[-1]
>>> 4
heapq.heappop(queue)[-1]
>>> 3
heapq.heappop(queue)[-1]
>>> 5

Функции heapq.heap push() и heapq.heappop() вставляют и удаляют элементы из списка _queue таким образом, чтобы первый элемент в списке имел наименьший приоритет. Вот почему мы вставляем индекс приоритета (первый элемент кортежа) как отрицательное число.

Поддержание словаря в порядке

если вы хотите сохранить словарь в порядке, вы можете использовать структуру OrderDict. OrderedDict может быть особенно полезен, когда вы хотите построить сопоставление, которое вы, возможно, захотите позже сериализовать или закодировать в другом формате.

from collections import OrderedDict
d = OrderedDict() 
d['foo'] = 1 
d['bar'] = 2 
d['spam'] = 3 
d['grok'] = 4
for key in d: 
    print(key, d[key])
>>> "foo 1"
    "bar 2"
    "spam 3"
    "grok 4"

Расчет со словарем

Может быть случай, когда вы хотите выполнить вычисления, такие как минимум, максимум или сортировка в структуре данных словаря.

prices = {'ACME': 45.23, 
          'AAPL': 612.78, 
          'IBM': 205.55, 
          'HPQ': 37.20, 
            'FB': 10.75}
min_price = min(zip(prices.values(), prices.keys())) 
# min_price is (10.75, 'FB')
max_price = max(zip(prices.values(), prices.keys())) 
# max_price is (612.78, 'AAPL')
prices_sorted = sorted(zip(prices.values(), prices.keys())) 
# prices_sorted is [(10.75, 'FB'), (37.2, 'HPQ'),
# (45.23, 'ACME'), (205.55, 'IBM'),
# (612.78, 'AAPL')]

Решение с участием zip() решает проблему, «инвертируя» словарь в последовательность пар (значение, ключ). При сравнении таких кортежей сначала сравнивается элемент значения, а затем ключ.

Сортировка списка словарей по общему ключу

У вас есть два словаря и вы хотите выяснить, что у них может быть общего (одинаковые ключи, одинаковые значения и т. д.).

a={'x' : 1, 'y' : 2, 'z' : 3 }
b={'w' : 10, 'x' : 11, 'y' : 2 }
# Find keys in common
a.keys() & b.keys() # { 'x', 'y' }
# Find keys in a that are not in b 
a.keys() - b.keys() # { 'z' }
# Find (key,value) pairs in common 
a.items() & b.items() # { ('y', 2) }
# Make a new dictionary with certain keys removed
c = {key:a[key] for key in a.keys() - {'z', 'w'}} 
# c is {'x': 1, 'y': 2}

Малоизвестная особенность представлений ключей заключается в том, что они также поддерживают общие операции с множествами, такие как объединение, пересечение и различие.

Сортировка списка словарей по общему ключу

У вас есть список словарей, и вы хотите отсортировать записи в соответствии с одним или несколькими значениями словаря.

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_fname = sorted(rows, key=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid')) 
print(rows_by_fname)
print(rows_by_uid)
#output 
>>>[{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}, {'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}, {'fname': 'David', 'uid': 1002, 'lname': 'Beazley'}, {'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}]
>>>[{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}, {'fname': 'David', 'uid': 1002, 'lname': 'Beazley'}, {'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}, {'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}]

Заключение

В этой короткой статье приведены некоторые полезные рецепты в контексте структуры данных. Надеюсь, это полезно :)