standings
[{'driver': 'Max Verstappen', 'team': 'Red Bull', 'home_country': 'Netherlands', 'points': 0}, {'driver': 'Lewis Hamilton', 'team': 'Mercedes', 'home_country': 'United Kingdom', 'points': 0}, {'driver': 'George Russell', 'team': 'Mercedes', 'home_country': 'United Kingdom', 'points': 0}, {'driver': 'Sergio Perez', 'team': 'Red Bull', 'home_country': 'Mexico', 'points': 0}, {'driver': 'Lando Norris', 'team': 'McLaren', 'home_country': 'United Kingdom', 'points': 0}, {'driver': 'Charles Leclerc', 'team': 'Ferrari', 'home_country': 'Monaco', 'points': 0}, {'driver': 'Valtteri Bottas', 'team': 'Ferrari', 'home_country': 'Spain', 'points': 0}]
driver_with_points
{'Carlos Sainz': 18, 'Charles Leclerc': 26, 'Esteban Ocon': 6, 'Fernando Alonso': 2, 'George Russell': 12, 'Kevin Magnussen': 10, 'Lewis Hamilton': 15, 'Valtteri Bottas': 8, 'Yuki Tsunoda': 4, 'Zhou Guanyu': 1}
I have to update the standings list depending on the points of driver in driver_with_points
dictionary, if driver name exists in driver_with_points
dictionary.
The task is done simply by the following lines.
for driver in standings:
if driver["driver"] in drivers_with_points.keys():
driver["points"] = drivers_with_points[driver["driver"]]
But I need to do the similar task by using list comprehension.
Can anyone help me convert this for loop to list comprehension?
I have tried
[driver["points"]=drivers_with_points[driver["driver"]] for driver in standings if driver["driver"] in drivers_with_points.keys()]
but it's error Unresolved reference 'drivers_with_points
CodePudding user response:
There is nothing wrong with doing this using a comprehension, but you shouldn't aim at updating an existing data structure. With a comprehension you should be making a new list rather than mutating the original. Comprehensions come from functional programming where immutable data is an aim.
You can use a list comprehension to make a new list which you can then assign to standings
. One way to do this is by unpacking the original dict and replacing the points with either the value from driver_with_points
or the original if not found. dict.get(key, some_default)
is a good pattern for this.
Consider:
standings = [{'driver': 'Max Verstappen', 'team': 'Red Bull', 'home_country': 'Netherlands', 'points': 0}, {'driver': 'Lewis Hamilton', 'team': 'Mercedes', 'home_country': 'United Kingdom', 'points': 0}, {'driver': 'George Russell', 'team': 'Mercedes', 'home_country': 'United Kingdom', 'points': 0}, {'driver': 'Sergio Perez', 'team': 'Red Bull', 'home_country': 'Mexico', 'points': 0}, {'driver': 'Lando Norris', 'team': 'McLaren', 'home_country': 'United Kingdom', 'points': 0}, {'driver': 'Charles Leclerc', 'team': 'Ferrari', 'home_country': 'Monaco', 'points': 0}, {'driver': 'Valtteri Bottas', 'team': 'Ferrari', 'home_country': 'Spain', 'points': 0}]
drivers_with_points = {'Carlos Sainz': 18, 'Charles Leclerc': 26, 'Esteban Ocon': 6, 'Fernando Alonso': 2, 'George Russell': 12, 'Kevin Magnussen': 10, 'Lewis Hamilton': 15, 'Valtteri Bottas': 8, 'Yuki Tsunoda': 4, 'Zhou Guanyu': 1}
# make a new list with new dicts:
standings = [{**s, 'points': drivers_with_points.get(s['driver'], s['points'])} for s in standings]
This will give you a new list and assign it standings
with:
[{'driver': 'Max Verstappen',
'team': 'Red Bull',
'home_country': 'Netherlands',
'points': 0},
{'driver': 'Lewis Hamilton',
'team': 'Mercedes',
'home_country': 'United Kingdom',
'points': 15},
{'driver': 'George Russell',
'team': 'Mercedes',
'home_country': 'United Kingdom',
'points': 12},
{'driver': 'Sergio Perez',
'team': 'Red Bull',
'home_country': 'Mexico',
'points': 0},
{'driver': 'Lando Norris',
'team': 'McLaren',
'home_country': 'United Kingdom',
'points': 0},
{'driver': 'Charles Leclerc',
'team': 'Ferrari',
'home_country': 'Monaco',
'points': 26},
{'driver': 'Valtteri Bottas',
'team': 'Ferrari',
'home_country': 'Spain',
'points': 8}]
CodePudding user response:
You can't do assignment (A=B) in a comprehension. You could possibly use the update function. For example:
[driver.update({'points': drivers_with_points[driver["driver"]]}) for driver in standings if driver["driver"] in drivers_with_points.keys()]