[英]Python: sort by attributes of a user-defined object object, in custom-defined order with a lambda function
我有一個自定義對象列表,它們具有兩個(重要)屬性、一個州代碼(TX、CA、NY 等)和一個年級(PK=preK、ES = 小學等)。 我需要按年級對這個列表進行排序,然后按州代碼的字母順序排序。 我現在擁有的是:
class myObject:
def __init__(self, state, grade):
self.state = state
self.grade = grade
myObjects = []
myObjects.append(myObject("KY", "HS"))
myObjects.append(myObject("AL", "ES"))
myObjects.append(myObject("NY", "PK"))
myObjects.append(myObject("CA", "PK"))
possibleGrades = ["PK", "K", "ES", "MS", "HS"]
myObjects.sort(key=lambda x: (x.grade, x.state))
for x in myObjects:
print("Grade: {}, State: {}".format(x.grade, x.state))
輸出:
Grade: ES, State: AL
Grade: HS, State: KY
Grade: PK, State: CA
Grade: PK, State: NY
我想要的是:
Grade: PK, State: CA
Grade: PK, State: NY
Grade: ES, State: AL
Grade: HS, State: KY
我按年級對 myObjects 進行排序,然后說明,但把小學放在 PreK 之前,因為我不知道如何指定排序的順序為可能的等級。 我知道有一種方法可以使用 .index 就像在這里使用https://www.geeksforgeeks.org/python-sort-list-according-to-other-list-order/來按自定義順序排序,但我可以不知道如何使用對象的屬性來做到這一點。 看起來它應該是這樣的:
standards.sort(key=lambda x: (x.grade, x.state) possibleGrades.index(x))
或者,分兩次:
standards.sort(key=lambda x: x.grade possibleGrades.index(x))
standards.sort(key=lambda x: x.state)
但那些不起作用。 我知道您可以通過多次傳遞進行排序以按多個屬性進行排序,我不喜歡一次傳遞進行排序,這只是最近的一次迭代,它讓我覺得 Python 可能能夠做到這一點做。 在最壞的情況下,我可以用 def 編寫一個完整的函數來對其進行排序,但是在我這樣做之前,是否有更多的 Pythonic 方法可以像我試圖做的那樣使用 lambda 對其進行排序?
嘗試這個:
myObjects.sort(key=lambda x: (possibleGrades.index(x.grade), x.state))
這首先按possibleGrades
Grades列表中的等級索引排序,然后按狀態排序。
正如@a_guest 所建議的,您還可以從列表中構建一個字典,特別是如果它是一個大列表,並進行 O(1) 查找。 然后代碼將如下所示:
grades = {g: i for i, g in enumerate(possibleGrades)}
myObjects.sort(key=lambda x: (grades[x.grade], x.state))
這是使用預構建排序字典和functools.partial將其放入 sort 的 1 參數鍵函數的答案。
class myObject:
def __init__(self, state, grade):
self.state = state
self.grade = grade
myObjects = []
myObjects.append(myObject("KY", "HS"))
myObjects.append(myObject("AL", "ES"))
myObjects.append(myObject("NY", "PK"))
myObjects.append(myObject("CA", "PK"))
possibleGrades = ["PK", "K", "ES", "MS", "HS"]
# grade sort attribute is their position in the list
di_sort = {item: ix for ix, item in enumerate(possibleGrades)}
print("di_sort:", di_sort)
def key(x, di_sort):
""" return a tuple of (grade sort, state)"""
return (di_sort.get(x.grade), x.state)
# sort's `key` function parameter is only expected to take
# one parameter, an item in the list, so `key` needs adjusting
from functools import partial
key = partial(key, di_sort=di_sort)
myObjects.sort(key=key)
for x in myObjects:
print("Grade: {}, State: {}".format(x.grade, x.state))
di_sort: {'PK': 0, 'K': 1, 'ES': 2, 'MS': 3, 'HS': 4}
Grade: PK, State: CA
Grade: PK, State: NY
Grade: ES, State: AL
Grade: HS, State: KY
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.