Современные подходы к хранению пар значений в языке Python

Раздел: Коллекции -> Коллекции

Основные способы работы с парами значений

Наиболее эффективным инструментом для хранения пар значений в Python является словарь (dict). Словарь обеспечивает доступ к значению по уникальному ключу за константное время (амортизированное O(1)).

Пример создания словаря и обращения к элементам:


# Создание словаря с парами 'страна: столица'
capitals = {"Россия": "Москва", "Франция": "Париж"}
print(capitals["Россия"])  # Москва
capitals["Германия"] = "Берлин"
  

Python set list (set и list в python: различия и использование)

Москва

Python пары значений (пары значений в python)

Словари идеально подходят для ассоциативных массивов, где ключи - уникальные идентификаторы.

Типичная ошибка: обращение по несуществующему ключу вызывает KeyError. Используйте метод get() с значением по умолчанию.


print(capitals.get("Италия", "Не найдено"))  # Не найдено
    

Python object get (метод get для объектов в python)

Не найдено

Python get keys (метод get для словарей в python)

Как сохранять упорядоченные пары без ключей?

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


pair = (10, 20)
print(pair[0])  # 10
# Список пар
coordinates = [(1, 2), (3, 4), (5, 6)]
  

Get index python (метод index в python)

Кортежи неизменяемы. Если требуется изменить значение, заменяйте весь кортеж.

Как объединить два списка в пары элементов?

Функция zip() создаёт итератор кортежей из нескольких последовательностей.


names = ["Аня", "Боря", "Витя"]
scores = [85, 92, 78]
pairs = list(zip(names, scores))
print(pairs)
  

Python get methods (методы get в python)

[('Аня', 85), ('Боря', 92), ('Витя', 78)]

Python длина списка (длина списка и массива в python)

Если списки разной длины, zip() обрезает до самой короткой последовательности. Используйте zip_longest из модуля itertools для сохранения всех элементов.

Как создать словарь с значениями по умолчанию для отсутствующих ключей?

Класс defaultdict из модуля collections автоматически добавляет отсутствующий ключ с заданным значением.


from collections import defaultdict
counter = defaultdict(int)
for word in ["яблоко", "банан", "яблоко"]:
    counter[word] += 1
print(dict(counter))
  

словарь данных python (словарь данных в python)

{'яблоко': 2, 'банан': 1}

типы данных python кортеж (кортеж (tuple) в python)

Не путайте defaultdict с обычным словарём - при обращении к несуществующему ключу он не вызывает ошибку, а создаёт новую пару.

Как сохранить порядок добавления пар ключ-значение?

Начиная с Python 3.7 словари по умолчанию сохраняют порядок вставки. Для обратной совместимости или явного указания используется OrderedDict.


from collections import OrderedDict
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od["c"] = 3
print(list(od.keys()))  # ['a', 'b', 'c']
  

Python типы данных set (множество (set) в python)

Методы move_to_end() и popitem(last=True) работают только с OrderedDict.

Как подсчитать частоту элементов в последовательности?

Класс Counter - подкласс словаря, специально созданный для подсчёта.


from collections import Counter
cnt = Counter("abracadabra")
print(cnt)
print(cnt.most_common(2))
  
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
[('a', 5), ('b', 2)]

Попытка обращения к отсутствующему ключу возвращает 0, а не KeyError.

Как создать именованные пары с доступом по атрибутам?

Класс namedtuple из collections создаёт неизменяемые объекты с именованными полями.


from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)
  
10 20

Имена полей должны быть строками без пробелов. Для изменяемых объектов используйте dataclass.

Как удобно объявить класс для пар с изменяемыми полями?

Декоратор @dataclass (модуль dataclasses) автоматически генерирует методы __init__, __repr__ и другие.


from dataclasses import dataclass

@dataclass
class Pair:
    first: str
    second: int

obj = Pair("A", 1)
obj.first = "B"
print(obj)
  
Pair(first='B', second=1)

Не забудьте указать типы полей. Если тип не важен, используйте Any из typing.

Каждый вариант имеет свою нишу: словари - для быстрого поиска по ключу, кортежи - для фиксированных последовательностей, namedtuple и dataclass - для структурированных данных с семантическими именами.

Расширенные примеры и редкие сценарии

Рассмотрим менее распространённые, но полезные техники работы с парами значений.

Как объединить несколько словарей в одну цепочку?

Класс ChainMap из модуля collections позволяет рассматривать несколько словарей как единое целое без копирования.

Пример

from collections import ChainMap
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
chain = ChainMap(d1, d2)
print(chain['b'])  # 2 (берётся из первого словаря)
print(list(chain.keys()))
2
['c', 'b', 'a']

Мутации через ChainMap затрагивают только первый словарь. Для обновления всех словарей используйте new_child().

Как создать пары из двух списков с разной длиной, не теряя элементы?

Функция zip_longest из itertools дополняет отсутствующие элементы указанным значением (по умолчанию None).

Пример

from itertools import zip_longest
list1 = [1, 2, 3]
list2 = ['a', 'b']
result = list(zip_longest(list1, list2, fillvalue='?'))
print(result)
[(1, 'a'), (2, 'b'), (3, '?')]

Не забудьте импортировать zip_longest. Для больших данных итератор экономит память.

Как преобразовать список пар в словарь с агрегацией значений?

Если ключи повторяются, можно использовать defaultdict со списком.

Пример

pairs = [('a', 1), ('b', 2), ('a', 3)]
from collections import defaultdict
d = defaultdict(list)
for k, v in pairs:
    d[k].append(v)
print(dict(d))
{'a': [1, 3], 'b': [2]}

Как получить пары из уникальных комбинаций элементов?

Используйте combinations из модуля itertools.

Пример

from itertools import combinations
items = [1, 2, 3]
pairs = list(combinations(items, 2))
print(pairs)
[(1, 2), (1, 3), (2, 3)]

combinations не учитывает порядок. Для упорядоченных пар используйте permutations.

Как инвертировать пары ключ-значение в словаре?

Генератор словаря с проверкой уникальности значений.

Пример

original = {'a': 1, 'b': 2, 'c': 1}
# Если значения уникальны, можно просто:
inv = {v: k for k, v in original.items()}
print(inv)
{1: 'c', 2: 'b'}

При повторяющихся значениях более поздний ключ перезапишет предыдущий. Для сохранения всех связей используйте defaultdict(list).

Пример

from collections import defaultdict
inv_multi = defaultdict(list)
for k, v in original.items():
    inv_multi[v].append(k)
print(dict(inv_multi))
  
{1: ['a', 'c'], 2: ['b']}

Как хранить пары в неизменяемом множестве?

Кортежи можно помещать во множество set или frozenset, если они неизменяемы.

Пример

pairs_set = {(1, 2), (3, 4)}
pairs_set.add((1, 2))  # не добавится, уже есть
print(pairs_set)
{(1, 2), (3, 4)}

Список кортежей не может быть помещён во множество, так как он изменяем. Преобразуйте его в frozenset кортежей.

Как объединить два словаря с обработкой конфликтов?

Начиная с Python 3.9 оператор | объединяет словари, заменяя старые ключи новыми.

Пример

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
merged = d1 | d2
print(merged)
{'a': 1, 'b': 3, 'c': 4}

Если требуется сохранить все значения конфликтующих ключей, используйте defaultdict(list) с ручным обходом.

Эти приёмы дополняют базовые методы и помогают решать специфические задачи: цепочечный поиск, работа с неполными данными, агрегация, инверсия и комбинаторика.

Пары значений в Python - comments

En
Python пары значений (python)