Python Forum

Full Version: sort list of dictionaries by value
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i am trying to sort a list of dictionaries based by a value of a specific key under the column of name values. i found two ways to do this
first i found


new_lst=sorted(lst,key=itemgetter(name))
this gives me an error code of

Error:
TypeError: unhashable type: 'list'
i have also tried



new_lst=sorted(lst,key=lambda d: d["name"])
the latter one gives me an error of


Error:
TypeError: list indices must be integers or slices, not str
i have scoured the net and i cant understand why these methods dont work.... please help
In this:
new_lst=sorted(lst,key=lambda d: d["name"])
d must not be a dictionary. What is in lst? It isn't dictionaries

In this code I create a list of dictionaries containing information about files in my folder. I then sort by is_dir, extension and finally filename.
from pathlib import Path

files = [{"name": x.name, "ext": x.suffix, "isdir": x.is_dir()} for x in Path(".").iterdir()]

print(*sorted(files, key=lambda x: (x["isdir"], x["ext"], x["name"])), sep="\n")
Output:
{'name': 'data.csv', 'ext': '.csv', 'isdir': False} {'name': 'input.csv', 'ext': '.csv', 'isdir': False} {'name': 'test.csv', 'ext': '.csv', 'isdir': False} {'name': 'interactiveconsole.py', 'ext': '.py', 'isdir': False} {'name': 'test_dir_sort.py', 'ext': '.py', 'isdir': False} {'name': 'test.txt', 'ext': '.txt', 'isdir': False} {'name': 'data.xlsx', 'ext': '.xlsx', 'isdir': False} {'name': '.vscode', 'ext': '', 'isdir': True} {'name': '__pycache__', 'ext': '', 'isdir': True} {'name': 'fastapi_demo', 'ext': '', 'isdir': True} {'name': 'games', 'ext': '', 'isdir': True} {'name': 'venv', 'ext': '', 'isdir': True}
itemgetter also works fine. Here I sort by name.
from pathlib import Path
from operator import itemgetter

files = [{"name": x.name, "ext": x.suffix, "isdir": x.is_dir()} for x in Path(".").iterdir()]
print(*sorted(files, key=itemgetter("name")), sep="\n")
From the error messages I think lst is a list of lists or tuples.
from pathlib import Path
from operator import itemgetter

files = [(x.name, x.suffix, x.is_dir) for x in Path(".").iterdir()]
print(*sorted(files, key=itemgetter("name")), sep="\n")
Error:
Traceback (most recent call last): File ...", line 5, in <module> print(*sorted(files, key=itemgetter("name")), sep="\n") TypeError: tuple indices must be integers or slices, not str
Change
new_lst = sorted(lst,key=itemgetter(name))
to

new_lst = sorted(lst,key=itemgetter("name"))
Example:


from operator import itemgetter

# somewhere in your code is a list assigned to name
name = []

# example of list of dicts with content
dicts = [{"value": x, "name": f"name{x}"} for x in range(1, 11)]

# somewhere else you are accessing the name, which is a list
# if name were not defined, you'll get instead an NameError

# but here you'll get an TypeError, because a dict can not have a mutable key
# and name is a list
# sorted_dicts = sorted(dicts, key=itemgetter(name))

# this is right
sorted_dicts = sorted(dicts, key=itemgetter("name"))

print("Before")
print(dicts)
print()

print("After")
print(sorted_dicts)
Additional task: Try to understand, why {'value': 10, 'name': 'name10'} is the second element in the list after the sorting.
Here is the correct usage using itemgetter and lambda.

Using itemgetter:
from operator import itemgetter

lst = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]

new_lst = sorted(lst, key=itemgetter("name"))
print(new_lst)
Output:
Output:
[{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 20}]
Using lambda:
lst = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]

new_lst = sorted(lst, key=lambda d: d["name"])
print(new_lst)
Output:
Output:
[{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 20}]
In this example:
new_lst=sorted(lst,key=itemgetter(name))
Error:
Error: TypeError: unhashable type: 'list'
The error message tells ups that name is a list. You should use a key name, like "name", but that is not going to fix your problem.

In this example:
new_lst=sorted(lst,key=lambda d: d["name"])
Error:
Error: TypeError: list indices must be integers or slices, not str
The error mesage tells us that d, one of the things in lst, is a list. lst is not a list of dictionaries, it is a list of lists. Fix that problem first.