Below is an example nested list of dictionaries. I want to order the lists by the number of points that Charlie has.
l = [[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20 },
{'Name': 'Charlie', 'Age': 30, 'Point': 10}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20 },
{'Name': 'Charlie', 'Age': 30, 'Point': 30}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20 },
{'Name': 'Charlie', 'Age': 30, 'Point': 20}]]
The output should look like this.
l = [[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20 },
{'Name': 'Charlie', 'Age': 30, 'Point': 10}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20 },
{'Name': 'Charlie', 'Age': 30, 'Point': 20}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20 },
{'Name': 'Charlie', 'Age': 30, 'Point': 30}]]
I think I should be able to use sorted() with the right arguments, but I'm not sure what the syntax would be.
sorted(l, key=lambda x: x[ ????? ])
Charlie is always the third item in the sublists.
CodePudding user response:
Use a lambda to search for Charlie's point in the nested lists:
l.sort(key=lambda lst: next(d.get('Point', 0) for d in lst if d.get('Name')=='Charlie'))
print(l)
If you want a new list:
out = sorted(l, key=lambda lst: next(d.get('Point', 0) for d in lst if d.get('Name')=='Charlie'))
Output:
[[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 10}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 20}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 30}]]
CodePudding user response:
Very similar to @enke's answer, but using next to provide the default 0, rather than the get method.
s = sorted(l, key=lambda lst: next((d['Point'] for d in lst if d['Name'] == 'Charlie'), 0))
CodePudding user response:
If Charlie is always third, you could use this:
sorted(l, key=lambda x: x[2]['Point'])
Otherwise, you'd want to use a helper function:
def get_charlie_points(lst):
for item in lst:
if item['Name'] == 'Charlie':
return item['Point']
return 0 # Replace this with the number you want if there is no Charlie, or raise an exception
sorted(l, key=get_charlie_points)
CodePudding user response:
If Charlie is always third, keep it simple, use:
out = sorted(l, key=lambda x:x[2].get('Point', float('inf')))
NB. I used a default value of infinite if Charlie has no points, to push it to the end.
Output:
[[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 10}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 20}],
[{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 30}]]
