Именованные кортежи (NamedTuples) — это отличный способ сделать ваш код на Python более полезным и читаемым. Если говорить коротко, именованный кортеж — это альтернатива встроенному кортежу. От стандартного кортежа именованный отличается тем, что к его элементам можно обращаться как по имени атрибута, так и по позиционному индексу, подобно тому, как это делается в Pandas DataFrame.
От редакции Pythonist: о датафреймах Pandas читайте в статье «Как создать Pandas DataFrame».
Примечание автора: код для этого руководства доступен по ссылке: https://github.com/StatsGary/PyHacks-Tutorials/blob/main/27_namedtuples.py.
Создание списка кортежей для сравнения
Сначала мы создадим список обычных кортежей с именами рокеров и названиями групп:
rockers_list = [ ('Dave Grohl', ' Foo Fighters'), ('Jimmy Page', 'Led Zeppelin'), ('Robert Plant', 'Led Zeppelin'), ('Roger Daltrey', 'The Who'), ('James Hetfield', 'Metallica'), ('Dave Mustaine', 'Megadeth'), ('Eddie Vedder', 'Pearl Jam'), ('Ronnie James Dio', 'Dio'), ('Howard Jones', 'Killswitch Engage') ]
Затем создадим стандартный цикл для вывода результатов:
for rocker in rockers_list: print('The rockers name is {}'.format(rocker[0]))
Единственный способ получить имя рокера из такого списка кортежей — использовать позиционный индекс. В примере мы берем индекс 0, чтобы получить первый элемент кортежа (имя), а название группы будет под индексом 1. Это ограничение стандартных кортежей.
Вывод:
The rockers name is Dave Grohl The rockers name is Jimmy Page The rockers name is Robert Plant The rockers name is Roger Daltrey The rockers name is James Hetfield The rockers name is Dave Mustaine The rockers name is Eddie Vedder The rockers name is Ronnie James Dio The rockers name is Howard Jones
Именованные кортежи и их возможности
Приступаем к использованию namedtuple. Во-первых, нам нужно импортировать его из пакета collections:
from collections import namedtuple
Реализация namedtuple
Для начала нам нужно реализовать структуру именованного кортежа:
Rockers = namedtuple('Rockers', ['rocker_name', 'band'])
Здесь я создаю namedtuple с именем Rockers
и затем передаю атрибуты. Поскольку у меня есть только имена рокеров и названия групп, именно эти два атрибута я и буду передавать.
Создание списка с помощью обертки namedtuple
Далее я создам список, как в первом примере, но на этот раз внутренние кортежи я создам с именем переменной, которое я определил. В данном случае это будет Rockers
, поскольку именно так я назвал свою переменную для namedtuple, но у вас может быть любое другое имя. Реализация:
rocker_named_tuple_list = [ Rockers('Dave Grohl', ' Foo Fighters'), Rockers('Jimmy Page', 'Led Zeppelin'), Rockers('Robert Plant', 'Led Zeppelin'), Rockers('Roger Daltrey', 'The Who'), Rockers('James Hetfield', 'Metallica'), Rockers('Dave Mustaine', 'Megadeth'), Rockers('Eddie Vedder', 'Pearl Jam'), Rockers('Ronnie James Dio', 'Dio'), Rockers('Howard Jones', 'Killswitch Engage') ]
Как видите, реализация соответствует определенной нами структуре namedtuple.
Перебор списка в цикле и обращение к элементам по имени
Как было сказано в начале этой статьи, именованные кортежи дают возможность обращаться к элементам и по индексу, и по имени. В нашем примере мы пройдемся по списку и выведем и имена рокеров, и названия групп.
for rocker in rocker_named_tuple_list: print(f'Rocker is: {rocker.rocker_name} and band is: {rocker.band}')
Результат:
Rocker is: Dave Grohl and band is: Foo Fighters Rocker is: Jimmy Page and band is: Led Zeppelin Rocker is: Robert Plant and band is: Led Zeppelin Rocker is: Roger Daltrey and band is: The Who Rocker is: James Hetfield and band is: Metallica Rocker is: Dave Mustaine and band is: Megadeth Rocker is: Eddie Vedder and band is: Pearl Jam Rocker is: Ronnie James Dio and band is: Dio Rocker is: Howard Jones and band is: Killswitch Engage
Изменение значения в именованном кортеже
Помимо вывода на экран, безусловно, можно выполнять и другие манипуляции с кортежами. Предположим, я хочу изменить значение группы Дэйва Грола на Nirvana, так как технически он был участником обеих групп. Сделать это можно следующим образом.
Я возьму Dave Grohl по индексу 0, а затем заменю один из элементов кортежа, band
, с Foo Fighters на Nirvana:
replace_example = rocker_named_tuple_list[0] # Get Dave Grohl and add his band to Nirvana replace_example = replace_example._replace(band='Nirvana') print(replace_example)
Вывод показывает, что это значение было изменено:
Rockers(rocker_name='Dave Grohl', band='Nirvana')
Другие возможности именованных кортежей
Есть еще два случая использования именованных кортежей, которые я хочу представить. Это преобразование списка и словаря в именованный кортеж.
Преобразование списка в именованный кортеж
Допустим, у вас есть список с той же структурой. Вы можете довольно просто конвертировать его в именованный кортеж:
# Автоматическое преобразование списка в именованный кортеж rocker_list_make = ['Kurt Cobain', 'Nirvana'] rocker_made_from_list = Rockers._make(rocker_list_make) print(rocker_made_from_list)
Как видите, при помощи команды ._make
мы превратили список в именованный кортеж:
Rockers(rocker_name='Kurt Cobain', band='Nirvana')
Вуаля!
Преобразование словаря в именованный кортеж
Процесс очень похож на описанный выше, но теперь у нас будет не список, а словарь. Вот как делается преобразование:
# Преобразование словаря в именованный кортеж my_rocker_dict = {'rocker_name': 'Zack De La Rocha', 'band':'Rage Against The Machine'} make_dict_named_tuple = Rockers(**my_rocker_dict) print(make_dict_named_tuple)
Мы использовали оператор распаковки для передачи нескольких kwargs
из словаря в именованный кортеж. Эти kwargs
становятся атрибутами и значениями именованного кортежа. В выводе мы получаем следующий результат:
Rockers(rocker_name='Zack De La Rocha', band='Rage Against The Machine')
От редакции Pythonist: о том, что такое kwargs, читайте в статье «Python *args and **kwargs».
Итоги
Мы разобрали, что собой представляют именованные кортежи в Python, чем они отличаются от обычных и как их создавать. Также мы на примерах рассмотрели преобразование списков и словарей в именованные кортежи.
Перевод статьи «Narly NamedTuples in Python».