В языке программирования Python есть несколько базовых структур для хранения данных.
Однако, наиболее популярные из них:
Преобразование данных из одного типа в другой — важнейшая составляющая любого языка программирования с динамической типизацией. И, разумеется, Python не исключение.
В этом руководстве будет подробно рассказано, что из себя представляют оба типа данных (список и словарь), а также рассмотрены способы преобразования одного типа в другой.
Все примеры, показанные в этой статье, ввыполнялись с использованием интерпретатора Python версии 3.10.12 в операционной системе Ubuntu 22.04, запущенной на облачном сервере Timeweb Cloud.
Список (list
) — это упорядоченная структура данных типа «индекс — значение».
Для создания списка используются квадратные скобки с перечислением значений через запятую:
my_list = [false, true, 2, 'три', 4, 5]
Структуру списка можно вывести в консоль:
print(my_list)
Выглядеть она будет так:
[false, true, 2, 'три', 4, 5]
Доступ к значениям списка осуществляется по индексам:
print(my_list[0]) # вывод: false
print(my_list[1]) # вывод: true
print(my_list[2]) # вывод: 2
print(my_list[3]) # вывод: три
print(my_list[4]) # вывод: 4
print(my_list[5]) # вывод: 5
Словарь (dict
) — это неупорядоченная структура данных типа «ключ — значение».
Для создания словаря используются фигурные скобки с перечислением ключей и значений, разделенных двоеточием, через запятую:
my_dict = {
'Виктор': '8 900 800 70 60',
'Александра': '8 750 640 53 42',
'Екатерина': '8 680 570 46 35'
}
Вывести структуру словаря в консоль можно следующим образом:
print(my_dict)
Выглядеть она будет так:
{'Виктор': '8 900 800 70 60', 'Александра': '8 750 640 53 42', 'Екатерина': '8 680 570 46 35'}
Доступ к значениям словаря осуществляется по ключам:
print(my_list['Виктор']) # вывод: 8 900 800 70 60
print(my_list['Александра']) # вывод: 8 750 640 53 42
print(my_list['Екатерина']) # вывод: 8 680 570 46 35
Преобразовать список в словарь можно несколькими способами:
dict.fromkeys()
, которая создает новый словарь с ключами из списка.Последний вариант предоставляет более гибкие возможности для генерации новых словарей из уже существующих списков.
Самый простой способ создать словарь из списка — взять элементы экземпляра list
и сделать их ключа экземпляра dict
. При этом для всех ключей нового словаря, если нужно, добавить значение по умолчанию.
Сделать это можно с помощью стандартной функции dict.fromkeys()
. При этом для всех ключей установить значение по умолчанию можно, а для каждого отдельного ключа — нельзя.
Вот пример создания такого словаря с ключами из списка:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль'] # список объектов
objects_states = dict.fromkeys(objects, 'злой') # создаем словарь из списка и назначаем значение для всех ключей по умолчанию
objects_states_empty = dict.fromkeys(objects) # создаем словарь из списка без указания значений по умолчанию
print(objects_states) # выводим в консоль созданный словарь со значениями
print(objects_states_empty) # выводим в консоль созданный словарь без значений
Консольный вывод будет следующим:
{'человек': 'злой', 'кот': 'злой', 'инопланетянин': 'злой', 'автомобиль': 'злой'}
{'человек': None, 'кот': None, 'инопланетянин': None, 'автомобиль': None}
Еще один способ превращения списка в ключи словаря — так называемый генератор словаря.
Этот метод более гибок и имеет больше возможностей по конфигурации нового словаря. Однако в самом простом случае генератор выполняет обыкновенный перебор списка, копируя все его элементы в качестве ключей в новый словарь вместе с заданным значением по умолчанию.
Вот так выглядит создание словаря из списка с помощью генератора:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
objects_states = {obj : 'злой' for obj in objects} # генератор словаря со строкой в качестве значения по умолчанию
objects_states_empty = {obj : None for obj in objects} # генератор словаря с пустым значением по умолчанию
print(objects_states)
print(objects_states_empty)
Консольный вывод будет аналогичным:
{'человек': 'злой', 'кот': 'злой', 'инопланетянин': 'злой', 'автомобиль': 'злой'}
{'человек': None, 'кот': None, 'инопланетянин': None, 'автомобиль': None}
В Python объект None
— это стандартное для большинства языков программирования специальное значение null
, которое означает отсутствие какого-либо значения. Объект None
имеет тип NoneType
:
print(type(None)) # вывод: <class 'NoneType'>
Более продвинутый способ — использовать 2 списка для генерации словаря. Один — для ключей, другой — для их значений.
Для этих целей существует специальная функция zip()
, с помощью которой можно выполнять итерацию сразу по нескольким объектам. В простых циклах эта функция используется так:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
states = ['идет', 'мурчит', 'маскируется', 'едет']
for q, w in zip(objects, states): print(q, w)
Вывод в консоли будет таким:
человек идет
кот мурчит
инопланетянин маскируется
автомобиль едет
Именно благодаря этой функции генератор словаря может одновременно подставлять элементы одного списка в качестве ключей, а элементы другого — в качестве значений.
В этом случае синтаксис записи генератора словаря не сильно отличается от обычного перебора:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль'] # список будущих ключей для нового словаря
states = ['идет', 'мурчит', 'маскируется', 'едет'] # список будущих значений для всех ключей нового словаря
objects_states = {obj : state for obj, state in zip(objects, states)} # генератор словаря с перебором списков ключей и значений
print(objects_states)
Консольный вывод будет таким:
{'человек': 'идет', 'кот': 'мурчит', 'инопланетянин': 'маскируется', 'автомобиль': 'едет'}
Может возникнуть закономерный вопрос, а что будет, если один из итерируемых списков будет короче, чем другой:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
states = ['идет', 'мурчит']
objects_states = {obj : state for obj, state in zip(objects, states)}
print(objects_states)
Вывод будет следующим:
{'человек': 'идет', 'кот': 'мурчит'}
Таким образом итерация в генераторе пароля выполняется по самому короткому из списков.
Тем не менее, код выше можно записать в крайне лаконичной форме:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
states = ['идет', 'мурчит', 'маскируется', 'едет']
objects_states = dict(zip(objects, states)) # создаем словарь из двух списков без цикла for
print(objects_states)
Консольный вывод будет такой же, как и предыдущие:
{'человек': 'идет', 'кот': 'мурчит', 'инопланетянин': 'маскируется', 'автомобиль': 'едет'}
Логика реальных приложений как правило сложнее показанных выше примеров — иногда необходимо преобразовывать списки в словари с учетом определенных условий.
Например, некоторые элементы должны попадать в новый словарь в измененном виде или не должны попадать совсем.
Для этого в генераторе словаря есть возможность создавать условия:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
states = ['идет', 'мурчит', 'маскируется', 'едет']
objects_states = {obj : state for obj, state in zip(objects, states) if obj != 'инопланетянин'} # защищаем Землю от воздействия неизвестной внеземной цивилизации
print(objects_states)
В этом случае консольный вывод окажется таким:
{'человек': 'идет', 'кот': 'мурчит', 'автомобиль': 'едет'}
Мы также можем создать несколько последовательных условий, чтобы конкретизировать выборку элементов при создании нового словаря:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
states = ['идет', 'мурчит', 'маскируется', 'едет']
objects_states = {obj : state for obj, state in zip(objects, states) if obj != 'инопланетянин' if obj != 'кот'} # убираем незамаскированное внеземное существо и кота — он может оказаться замаскированным гостем из другой галактики
print(objects_states)
Таким образом в консольный вывод становится следующим:
{'человек': 'идет', 'автомобиль': 'едет'}
Используя двух и более условных операторов в генераторе словаря важно помнить, что условия if
работают так, как если бы между ними находилось логическое and
.
Сделать генерацию словаря еще сложнее и гибче можно с помощью комбинации операторов if
и else
:
objects = ['человек', 'кот', 'инопланетянин', 'автомобиль']
states = ['идет', 'мурчит', 'маскируется', 'едет']
# в этом примере все строковые элементы первого списка длиннее, чем строковые элементы второго списка, кроме одного — 'кот'
objects_states = {obj : ('[ПОДОЗРИТЕЛЕН]' if len(obj) < len(state) else 'спокойно ' + state) for obj, state in zip(objects, states)} # находим подозрительного кота и помечаем его соответствующей биркой, а другие значения немного дополняем
print(objects_states)
Консольный вывод будет следующим:
{'человек': 'спокойно идет', 'кот': '[ПОДОЗРИТЕЛЕН]', 'инопланетянин': 'спокойно маскируется', 'автомобиль': 'спокойно едет'}
Во всех предыдущих примерах словарь создавался из двух списков. А что, если ключи и значения, необходимые для создания нового словаря, находятся в одном списке?
В этом случае потребуется усложнить логику генератора словаря:
objects_and_states = ['человек', 'идет', 'кот', 'мурчит', 'инопланетянин', 'маскируется', 'автомобиль', 'едет'] # ключи и значения последовательно записаны в один список
objects_states = {objects_and_states[i] : objects_and_states[i+1] for i in range(0, len(objects_and_states), 2)}
# в этом варианте генератора функция range настраивает длину и шаг итерирования: range(НАЧАЛО, КОНЕЦ, ШАГ)
print(objects_states)
В консольном терминале появится уже привычный вывод:
{'человек': 'идет', 'кот': 'мурчит', 'инопланетянин': 'маскируется', 'автомобиль': 'едет'}
В некоторых случаях список может содержать вложенные словари в качестве элементов. Их значения тоже могут стать частью нового словаря.
В этом случае логика генератора становится немного иной:
objects = [
{'имя': 'человек', 'состояние': 'идет', 'местонахождение': 'улица'},
{'имя': 'кот', 'состояние': 'мурчит', 'местонахождение': 'подоконник'},
{'имя': 'инопланетянин', 'состояние': 'маскируется', 'местонахождение': 'звездолет'},
{'имя': 'автомобиль', 'состояние': 'едет', 'местонахождение': 'шоссе'}
]
objects_states = {obj['имя'] : obj['состояние'] for obj in objects}
print(objects_states)
Вывод в терминал консоли не отличается от предыдущих:
{'человек': 'идет', 'кот': 'мурчит', 'инопланетянин': 'маскируется', 'автомобиль': 'едет'}
Преобразовать словарь в список — довольно простая задача. Правда правильнее было бы называть это «извлечением» данных.
Из одного словаря можно получить несколько списков:
Сделать это можно следующими методами:
objects_states = {
'человек': 'идет',
'кот': 'мурчит',
'инопланетянин': 'маскируется',
'автомобиль': 'едет'
}
# все возвращаемые объекты в явном виде конвертируются в списки с помощью функции list()
objects_keys = list(objects_states.keys()) # список с ключами словаря
objects_values = list(objects_states.values()) # список со значениями словаря
objects_items = list(objects_states.items()) # список с парами «ключ-значение» словаря
print(objects_keys)
print(objects_values)
print(objects_items)
Вывод в терминале будет таким:
['человек', 'кот', 'инопланетянин', 'автомобиль']
['идет', 'мурчит', 'маскируется', 'едет']
[('человек', 'идет'), ('кот', 'мурчит'), ('инопланетянин', 'маскируется'), ('автомобиль', 'едет')]
Список и словарь — это структуры данных в языке программирования Python, которые по-разному хранят данные и осуществляют доступ к ним.
Словарь более информативен, чем список: он хранит данные в виде пар «ключ — значение», в то время как список содержит только значения, к которым доступ осуществляется по индексам.
Поэтому есть несколько способов преобразования списка в словарь:
Инструмент |
Значение ключей |
Синтаксис |
|
общее |
|
генератор словаря |
общее |
|
генератор словаря + |
уникальное |
|
генератор словаря + |
уникальное |
|
генератор словаря + |
уникальное |
|
Данные, хранящиеся в нестандартных списках, требуют более сложной записи конфигурации генераторов словарей. Часть из таких записей была показана в этом руководстве, в том числе и вспомогательные функции для итераций, таких как zip()
и range()
.
Преобразование словаря в список тоже возможно несколькими способами, но гораздо проще:
Инструмент |
Извлекает |
Синтаксис |
|
ключи |
|
|
значения |
|
|
пары «ключ — значение» |
|
Таким образом, язык программирования Python предоставляет довольно гибкие возможности для преобразования структурированных (составных) типов данных из одного в другого — в данном случае списка в словарь и обратно.