Работа с парами в Python: кортежи, списки, zip

Раздел: Основы Python -> Кортежи и списки

Пары в 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')]

Пары в Python - comments

En
Python пары (python)