To come straight to the point:
def sortBy(dict, byWhat):
# byWhat is a list of 1 - 10 strings, which can include any of allAttributes
# allAttributes = ['name', 'kingdom', 'diff', 'tier', 'type', 'founder', 'prover', 'server', 'extra', 'link']
# the lower the index, the higher the sorting priority -> byWhat = ['name', 'diff'] then sort by name first and then if names are the same by diff
# dict has the name as key and then allAttributes above in order as a list for the key's value, so for example:
# dict[Jump] = [Jump, Mushroom Kingdom, 10/10, Triple Jump, Dude, Dude2, Main Server, Cool jump description, https://twitter.com]
# All dictionary entries have those 10 attributes, no exceptions
return dict # but sorted
I tried for a while but where my knowledge ends is sorting by a varying size of specifiers with lambda. I can also not just call the function multiple times, because then it won't sort by two attributes, but by the last attribute the function got called with.
CodePudding user response:
You can convert dict to list of (key, value) tuples and use list.sort(key)
method and utilizing functools.cmp_to_key
define key as compare function and then "inject" byWhat
parameter into compare function using functools.partial
from functools import cmp_to_key, partial
allAttributes = ["name", "age"]
def sortBy(d, byWhat):
def cmp(a, b, byWhat):
for k in byWhat:
index = allAttributes.index(k)
if a[1][index] != b[1][index]:
return -1 if a[1][index] < b[1][index] else 1
return 0
items = list(d.items())
items.sort(key=cmp_to_key(partial(cmp, byWhat=byWhat)))
return dict(items)
if __name__ == "__main__":
d = {
"foo": ["John", 12],
"bar": ["Adam", 12],
"baz": ["John", 10],
}
print(sortBy(d, ["name", "age"]))
CodePudding user response:
You can convert dict to list of (key, value) tuples, map byWhat
into indexes and use list.sort(key)
where key
is lambda returning list of attributes to sort by.
allAttributes = ["name", "age"]
def sortBy(d, byWhat):
indexes = [allAttributes.index(k) for k in byWhat]
items = list(d.items())
items.sort(key=lambda item: [item[1][index] for index in indexes])
return dict(items)
if __name__ == "__main__":
d = {
"foo": ["John", 12],
"bar": ["Adam", 12],
"baz": ["John", 10],
}
print(sortBy(d, ["name", "age"]))