我正在处理作为词典列表返回的数据。每个dicts需要按其值排序,并且一些dicts需要特别注意",就像自定义排序模式一样。
下面是一个简化的工作示例。我已经解决了这些问题(感谢SO的一些帮助)。示例输入在"桶和#34;中示出。字典。
我试图找到一种方法来解决问题"底部的3个单独的排序方法成为单个排序函数,以避免重复类似的代码。很难搞清楚。测试代码我写的基本上只是重新创建了我在这里所做的,但是在一个函数中: - |
# returned data to sort
buckets = {
'size_apparel' : [
{ 'doc_count': 86, 'key': 'M' },
{ 'doc_count': 12, 'key': 'S' },
{ 'doc_count': 44, 'key': 'L' },
{ 'doc_count': 44, 'key': 'Bazillion' } # outlier
],
'size_jewelry' : [
{ 'doc_count': 86, 'key': '7' },
{ 'doc_count': 12, 'key': '4.5' },
{ 'doc_count': 10, 'key': '6' },
{ 'doc_count': 2, 'key': '5' }
],
'color' : [
{ 'doc_count': 86, 'key': 'Zebra' },
{ 'doc_count': 12, 'key': 'Azure' },
{ 'doc_count': 44, 'key': 'Red' }
]
}
# list of all possible buckets, not used here but *could* be used
bucket_list = ['size_apparel','size_jewelry','state','color','cloth','style']
# custom sorting for apparel
apparel_map = ['S','M','L','XL','XXL','XXXL']
for key, value in buckets.items():
# apparel as a custom sort map defined in apparel_map
if key == 'size_apparel':
try:
buckets['size_apparel'] = sorted(buckets['size_apparel'],
key=lambda x:apparel_map.index(x['key']))
except ValueError:
pass
# jewelry sizes are sorted numerically, but need to be converted to float first
elif key == 'size_jewelry':
try:
buckets['size_jewelry'] = sorted(buckets['size_jewelry'],
key=lambda k: float(k['key']))
except ValueError:
pass
# everything else: sort by doc count descending
else:
try:
buckets[key] = sorted(buckets[key], key=lambda k: k['doc_count'], reverse=True)
except ValueError:
pass
try / except用于在数据集中返回异常值时,这将发生并且完全正常。 "传递"是因为他们不需要处理
答案 0 :(得分:1)
是的,您可以将所有键选逻辑移动到一个函数中,并使循环看起来更简单。
这是一种方法。
def key_function(name):
# custom sorting for apparel
apparel_map = ['S','M','L','XL','XXL','XXXL']
def key(d):
if name == 'size_apparel':
try:
return apparel_map.index(d['key'])
except ValueError:
return len(apparel_map)
elif name == 'size_jewelry':
try:
return float(d['key'])
except ValueError:
return sys.float_info.max
return -d['doc_count']
return key
for key, value in buckets.items():
value.sort(key=key_function(key))
答案 1 :(得分:0)
这是另一种方法,更模块化,可能更容易阅读 - 仍然没有考虑到尝试/排除但它开始看起来有点难看
import sys, operator
apparel_map = {k:i for i,k in enumerate(apparel_map)}
# or
apparel_map = {'S':0, 'M':1, 'L':2,'XL':3, 'XXL':4, 'XXXL':5}
my_key = operator.itemgetter('key')
doc_count = operator.itemgetter('doc_count')
def f(item):
'''size_apparel key function'''
try:
return apparel_map[my_key(item)]
except KeyError:
return sys.maxsize
def g(item):
'''size_jewelry key function'''
try:
return float(my_key(item))
except ValueError:
return sys.maxsize
def h(item):
'''generic key function'''
try:
return doc_count(item) * -1
except ValueError:
return sys.maxsize
sort_keys = {'size_apparel' : f,
'size_jewelry' : g}
for key, value in buckets.items():
try:
sort_key = sort_keys[key]
except KeyError:
sort_key = h
value.sort(key = sort_key)