Python 在三元运算符中使用operator.itemgetter作为排序键的可能性
有一个相同类型的词典列表-Python 在三元运算符中使用operator.itemgetter作为排序键的可能性,python,sorting,Python,Sorting,有一个相同类型的词典列表-项。我想得到一个统一的字典,其中包含映射中描述的排序名称以及按我需要的字段排序的这些字典的标题列表。字典和映射本身包含更多字段和描述的排序(请参见下面的代码) 一切正常,并显示此输出: { 'title-desc': ['D Item', 'C Item', 'B Item', 'A Item'], 'smth-asc': ['B Item', 'C Item', 'D Item', 'A Item'] } 但我面临着这样的挑战。字典包含两个字段-一
项
。我想得到一个统一的字典,其中包含映射中描述的排序名称以及按我需要的字段排序的这些字典的标题列表。字典和映射本身包含更多字段和描述的排序(请参见下面的代码)
一切正常,并显示此输出:
{
'title-desc': ['D Item', 'C Item', 'B Item', 'A Item'],
'smth-asc': ['B Item', 'C Item', 'D Item', 'A Item']
}
但我面临着这样的挑战。字典包含两个字段-一个
和两个
。字段one
始终填充,字段two
是可选的。是否可以使用三元运算符和itemgetter描述逻辑:如果字段two
包含数据,则使用它,否则使用字段one
?大概是这样的:
??=itemgetter('two')如果itemgetter('two')或者itemgetter('one')
,但它不会工作。
我预计这一产出:
{
'title-desc': [...],
'smth-asc': [...],
'one/two-asc': ['B Item', 'A Item', 'C Item', 'D Item']
}
或者还有什么其他的解决方案
提前感谢。如果您不使用itemgetter
来满足以下条件,则有可能:
# if the empty 'two' fields are filled with None
lambda x: x["two"] if x["two"] is not None else x["one"]
# if the 'two' key isn't in the dict instead of being filled with None:
lambda x: x["two"] if "two" in x else x["one"]
我没有使用if x[“two”]
作为条件,因为如果x[“two”]
也是0
,它将返回False
此外,没有必要对itemgetter函数使用lambda
,相反,请执行以下操作:
'smth-asc': {'key': itemgetter('something'), 'reverse': False},
'one/two-asc': {'key': lambda x: x["two"] if x["two"] is not None else x["one"], 'reverse': False}
然后,直接将这些函数用作排序键,而不调用它们:key=value['key']
您可以定义自己的“三元”itemgetter
类函数,该函数返回一个可调用的函数,该函数可以执行您想要的操作:
from operator import itemgetter
from pprint import pprint
def ternary_itemgetter(a, b):
return lambda obj: obj[b] if obj[b] is not None else obj[a]
items = [
{'title': 'C Item', 'something': 1.5, 'one': 2, 'two': 3},
{'title': 'B Item', 'something': 1.0, 'one': 1, 'two': None},
{'title': 'D Item', 'something': 1.5, 'one': 4, 'two': None},
{'title': 'A Item', 'something': 2.0, 'one': 3, 'two': 2},
]
mappings = {
'title-desc': {'key': lambda: itemgetter('title'), 'reverse': True},
'smth-asc': {'key': lambda: itemgetter('something'), 'reverse': False},
# ... Other ways to sort by other fields ...
'one/two-asc': {'key': lambda: ternary_itemgetter('one', 'two'), 'reverse': False},
}
results = {}
for key, value in mappings.items():
sorted_items = sorted(items, key=value['key'](), reverse=value['reverse'])
sorted_values = {key: [item['title'] for item in sorted_items]}
results.update(sorted_values)
pprint(results, sort_dicts=False)
输出:
{'title-desc':['D Item','C Item','B Item','A Item'],
'smth asc':['B项'、'C项'、'D项'、'A项'],
“一个/两个asc”:[“B项”、“A项”、“C项”、“D项”]]
from operator import itemgetter
from pprint import pprint
def ternary_itemgetter(a, b):
return lambda obj: obj[b] if obj[b] is not None else obj[a]
items = [
{'title': 'C Item', 'something': 1.5, 'one': 2, 'two': 3},
{'title': 'B Item', 'something': 1.0, 'one': 1, 'two': None},
{'title': 'D Item', 'something': 1.5, 'one': 4, 'two': None},
{'title': 'A Item', 'something': 2.0, 'one': 3, 'two': 2},
]
mappings = {
'title-desc': {'key': lambda: itemgetter('title'), 'reverse': True},
'smth-asc': {'key': lambda: itemgetter('something'), 'reverse': False},
# ... Other ways to sort by other fields ...
'one/two-asc': {'key': lambda: ternary_itemgetter('one', 'two'), 'reverse': False},
}
results = {}
for key, value in mappings.items():
sorted_items = sorted(items, key=value['key'](), reverse=value['reverse'])
sorted_values = {key: [item['title'] for item in sorted_items]}
results.update(sorted_values)
pprint(results, sort_dicts=False)