Работа с парами в Python: кортежи, списки, zip
Пары в Python: работа с кортежами и списками
Как создать пару значений в Python?
Наиболее эффективный способ представить пару - использовать кортеж (tuple) из двух элементов. Кортеж неизменяем, компактен и работает быстрее списка для фиксированной последовательности.
pair = (10, 'text') # кортеж из целого числа и строки
print(pair)Python пары (пары в python)
(10, 'text')
пары элементов python (работа с парами элементов)
Кортеж создаётся простым перечислением элементов в круглых скобках. Скобки можно опускать в большинстве контекстов:
pair = 10, 'text' # тоже кортеж
print(type(pair))
Типичная ошибка
Попытка изменить элемент кортежа вызывает TypeError. Например, pair[0] = 20 приведёт к ошибке. Если требуется изменяемая структура, используйте список (см. вариант ниже).
Как создать изменяемую пару?
Используйте список из двух элементов. В отличие от кортежа, список можно модифицировать: добавлять, удалять или заменять элементы.
pair_list = [10, 'text']
pair_list[0] = 20
print(pair_list)
[20, 'text']
Типичная ошибка
Список не ограничен двумя элементами. По ошибке можно добавить третий элемент: pair_list.append(30). Это нарушит логику «пары». Для строгого контроля используйте кортеж.
Как объединить два списка в список пар?
Функция zip последовательно соединяет элементы из переданных итераторов в кортежи. Это стандартный способ получить список пар из двух последовательностей.
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
pairs = list(zip(list1, list2))
print(pairs)
[(1, 'a'), (2, 'b'), (3, 'c')]
Zip останавливается на самой короткой последовательности.
Типичная ошибка
Если списки разной длины, лишние элементы отбрасываются. Чтобы сохранить все, используйте zip_longest из модуля itertools.
from itertools import zip_longest
list1 = [1, 2, 3, 4]
list2 = ['a', 'b', 'c']
pairs = list(zip_longest(list1, list2))
print(pairs)
[(1, 'a'), (2, 'b'), (3, 'c'), (4, None)]
Как извлечь элементы пары в отдельные переменные?
Распаковка кортежа (или любого итерируемого) в переменные - лаконичный способ получить каждый элемент.
pair = (5, 6)
x, y = pair
print(x, y)
5 6
Распаковка работает и со списками, и с любыми последовательностями фиксированной длины.
Типичная ошибка
Количество переменных должно совпадать с длиной последовательности. Иначе возникнет ValueError. Например, a, b = (1, 2, 3) вызовет ошибку.
Как отсортировать список пар по второму элементу?
Функция sorted с параметром key позволяет задать произвольный критерий сортировки. Для сортировки по второму элементу используйте функцию, возвращающую элемент с индексом 1.
pairs = [(1, 'b'), (2, 'a'), (3, 'c')]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
print(sorted_pairs)
[(2, 'a'), (1, 'b'), (3, 'c')]
Типичная ошибка
Забыть указать key. Тогда сортировка по умолчанию сравнивает кортежи целиком, сначала первый элемент, потом второй. Результат может не соответствовать ожиданиям.
pairs = [(1, 'b'), (2, 'a'), (3, 'c')]
print(sorted(pairs)) # будет по первому элементу
[(1, 'b'), (2, 'a'), (3, 'c')]
Как получить список пар ключ-значение из словаря?
Метод items() возвращает представление словаря в виде набора кортежей (key, value). Преобразуйте его в список для дальнейшей работы.
d = {'apple': 3, 'banana': 1, 'cherry': 2}
pairs = list(d.items())
print(pairs)
[('apple', 3), ('banana', 1), ('cherry', 2)]
Типичная ошибка
В версиях Python до 3.7 порядок элементов в словаре не гарантировался. В современных версиях порядок сохранения вставки соблюдается, но полагаться на него не стоит при переносе кода на старые версии.
Как создать именованные пары с полями first и second?
Именованный кортеж namedtuple из модуля collections позволяет обращаться к элементам по имени, что улучшает читаемость кода.
from collections import namedtuple
Pair = namedtuple('Pair', ['first', 'second'])
p = Pair(10, 'x')
print(p.first, p.second)
10 x
Типичная ошибка
Именованные кортежи, как и обычные, неизменяемы. Попытка p.first = 20 вызовет AttributeError. Для изменяемых именованных структур используйте SimpleNamespace или сторонние библиотеки.
Расширенные примеры работы с парами
Комбинирование zip и enumerate для создания пар с индексом
Используйте enumerate вместе с zip для получения пар, содержащих индекс исходного списка.
items = ['a', 'b', 'c', 'd']
indexed_pairs = list(enumerate(items))
print(indexed_pairs)
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Можно также создать пары, комбинируя zip с несколькими итераторами:
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
grades = ['B+', 'A', 'C+']
combined = list(zip(names, scores, grades))
print(combined[:2])
[('Alice', 85, 'B+'), ('Bob', 92, 'A')]
Обратите внимание: zip создаёт кортежи произвольной длины, а не только пары.
Сортировка по одной из частей пары с обратным порядком
Параметр reverse=True в sorted меняет порядок на противоположный.
pairs = [(1, 'c'), (2, 'b'), (3, 'a')]
# сортировка по второму элементу, от большего к меньшему (по алфавиту - от z к a)
sorted_rev = sorted(pairs, key=lambda x: x[1], reverse=True)
print(sorted_rev)
[(1, 'c'), (2, 'b'), (3, 'a')]
Преобразование списка пар в словарь
Функция dict() принимает итератор кортежей из двух элементов и строит словарь.
pairs = [('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')]
d = dict(pairs)
print(d)
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
Если ключи повторяются, остаётся последнее значение. Для обработки конфликтов используйте цикл.
Использование list comprehensions для создания пар
Генераторы списков позволяют гибко формировать пары по условию.
# пары (число, квадрат) для чисел от 1 до 5
pairs = [(n, n**2) for n in range(1, 6)]
print(pairs)
[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
Можно добавлять фильтрацию:
# только пары, где число чётное
even_pairs = [(n, n**2) for n in range(1, 11) if n % 2 == 0]
print(even_pairs)
[(2, 4), (4, 16), (6, 36), (8, 64), (10, 100)]
Распаковка пар в цикле for
Цикл for позволяет распаковывать каждый кортеж прямо в заголовке.
pairs = [(1, 'один'), (2, 'два'), (3, 'три')]
for number, name in pairs:
print(f"{number}: {name}")
1: один 2: два 3: три
Это же работает с enumerate:
letters = ['a', 'b', 'c']
for idx, letter in enumerate(letters):
print(f"{idx} -> {letter}")
0 -> a 1 -> b 2 -> c
Объединение нескольких пар в одну строку
Для вывода можно использовать join с генератором.
pairs = [('Moscow', 12), ('London', 15), ('Paris', 14)]
output = ', '.join(f"{city}: {temp}°" for city, temp in pairs)
print(output)
Moscow: 12°, London: 15°, Paris: 14°
Поиск минимума и максимума по одному из элементов пары
Функции min и max также поддерживают key.
pairs = [(4, 'apple'), (1, 'banana'), (5, 'cherry')]
# найти пару с минимальным первым элементом
min_first = min(pairs, key=lambda x: x[0])
print(min_first)
# найти пару с максимальным вторым элементом (по алфавиту)
max_second = max(pairs, key=lambda x: x[1])
print(max_second)
(1, 'banana') (5, 'cherry')
Фильтрация списка пар по условию
pairs = [(2, 'a'), (3, 'b'), (4, 'c'), (5, 'd')]
filtered = [(a, b) for a, b in pairs if a % 2 == 0]
print(filtered)
[(2, 'a'), (4, 'c')]