How to use dictionary comprehension to combine two lists into a nested dictionary?
Question:
I want to combine the following lists into a nested dictionary using list comprehension.
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = [
'PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
The dictionary should look like this:
python_events = {
0: {'time': '2023-04-01', 'name': 'PyTexas'},
1: {'time': '2023-04-07', 'name': 'PyCamp Spain'},
2: {'time': '2023-04-17', 'name': 'PyData Berlin'},
3: {'time': '2023-04-19', 'name': 'PyCon US'},
4: {'time': '2023-04-25', 'name': 'PyLadies Amsterdam'}}
I am trying to use dictonary comprehension mostly for learning and practice. It seems like a bad use case for comprehension since it most likely will not be readable at all, or at least doesn’t seem like it to me
My original way of creating the dict was looping through a range:
for i in range(0, len(dates)):
python_events[i] = {"time": dates[i], "name": events_name[i]}
Even after some research, and using comprehension for non nested dicts, I never managed to get valid code for my comprehension. I tried multiple variants of this:
python_events = {
i: {"time": date, "name": name for date, name in dict(foo).items()}
for i, date, name in range(0, len(events))}
I’m clearly missing some fundamental knowledge here, so any help on how to do this would be much appreciated.
Answers:
Yes, you can use a dict
comprehension to make python_events
like this:
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = ['PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
python_events = {i:{"time": date,"name": name } for i, (date, name) in enumerate(zip(dates,events_name))}
print(python_events)
Output as requested.
This code uses zip
to iterate through your two lists at the same time and also enumerate
to generate the index i
.
Use enumerate
to generate indices, and zip
to combine two lists pair-wise:
from pprint import pprint
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = ['PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
python_events = {i: {'time': date, 'name': event}
for i, (date, event) in enumerate(zip(dates, events_name))}
pprint(python_events)
Output:
{0: {'name': 'PyTexas', 'time': '2023-04-01'},
1: {'name': 'PyCamp Spain', 'time': '2023-04-07'},
2: {'name': 'PyData Berlin', 'time': '2023-04-17'},
3: {'name': 'PyCon US', 'time': '2023-04-19'},
4: {'name': 'PyLadies Amsterdam', 'time': '2023-04-25'}}
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = ['PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
python_events = {i: {'time': date, 'name': name} for i, (date, name) in enumerate(zip(dates, events_name))}
print(python_events)
The enumerate()
function is used in this snippet of code to retrieve the index and a tuple (date, name
) for each element in the lists of compressed dates and events names. Then, a nested dictionary comprising the entries "time" and "name" is created with the index as the key.
The key to converting a for-loop to a comprehension is knowing the pattern. Here’s some pseudocode:
d = {}
for x in iterable:
d[key_expression] = value_expression
That rearranges into a comprehension like this:
d = {key_expression: value_expression for x in iterable}
Note that for x in iterable
is exactly the same, just at the end, and the two expressions don’t need to change at all.
So, for your code:
python_events = {
i: {"time": dates[i], "name": events_name[i]} for i in range(0, len(dates))}
That said, you can use zip
and enumerate
to do this more cleanly, as others have answered.
I want to combine the following lists into a nested dictionary using list comprehension.
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = [
'PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
The dictionary should look like this:
python_events = {
0: {'time': '2023-04-01', 'name': 'PyTexas'},
1: {'time': '2023-04-07', 'name': 'PyCamp Spain'},
2: {'time': '2023-04-17', 'name': 'PyData Berlin'},
3: {'time': '2023-04-19', 'name': 'PyCon US'},
4: {'time': '2023-04-25', 'name': 'PyLadies Amsterdam'}}
I am trying to use dictonary comprehension mostly for learning and practice. It seems like a bad use case for comprehension since it most likely will not be readable at all, or at least doesn’t seem like it to me
My original way of creating the dict was looping through a range:
for i in range(0, len(dates)):
python_events[i] = {"time": dates[i], "name": events_name[i]}
Even after some research, and using comprehension for non nested dicts, I never managed to get valid code for my comprehension. I tried multiple variants of this:
python_events = {
i: {"time": date, "name": name for date, name in dict(foo).items()}
for i, date, name in range(0, len(events))}
I’m clearly missing some fundamental knowledge here, so any help on how to do this would be much appreciated.
Yes, you can use a dict
comprehension to make python_events
like this:
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = ['PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
python_events = {i:{"time": date,"name": name } for i, (date, name) in enumerate(zip(dates,events_name))}
print(python_events)
Output as requested.
This code uses zip
to iterate through your two lists at the same time and also enumerate
to generate the index i
.
Use enumerate
to generate indices, and zip
to combine two lists pair-wise:
from pprint import pprint
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = ['PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
python_events = {i: {'time': date, 'name': event}
for i, (date, event) in enumerate(zip(dates, events_name))}
pprint(python_events)
Output:
{0: {'name': 'PyTexas', 'time': '2023-04-01'},
1: {'name': 'PyCamp Spain', 'time': '2023-04-07'},
2: {'name': 'PyData Berlin', 'time': '2023-04-17'},
3: {'name': 'PyCon US', 'time': '2023-04-19'},
4: {'name': 'PyLadies Amsterdam', 'time': '2023-04-25'}}
dates = ['2023-04-01', '2023-04-07', '2023-04-17', '2023-04-19', '2023-04-25']
events_name = ['PyTexas', 'PyCamp Spain', 'PyData Berlin', 'PyCon US', 'PyLadies Amsterdam']
python_events = {i: {'time': date, 'name': name} for i, (date, name) in enumerate(zip(dates, events_name))}
print(python_events)
The enumerate()
function is used in this snippet of code to retrieve the index and a tuple (date, name
) for each element in the lists of compressed dates and events names. Then, a nested dictionary comprising the entries "time" and "name" is created with the index as the key.
The key to converting a for-loop to a comprehension is knowing the pattern. Here’s some pseudocode:
d = {}
for x in iterable:
d[key_expression] = value_expression
That rearranges into a comprehension like this:
d = {key_expression: value_expression for x in iterable}
Note that for x in iterable
is exactly the same, just at the end, and the two expressions don’t need to change at all.
So, for your code:
python_events = {
i: {"time": dates[i], "name": events_name[i]} for i in range(0, len(dates))}
That said, you can use zip
and enumerate
to do this more cleanly, as others have answered.