Python中对含整数与None值的字典按多键排序报错求助
解决Python3中含None值的字典排序问题
你遇到的问题核心是Python3严格限制了不同类型的比较规则——在Python2里,解释器会默认把None排在所有数值前面,所以operator.attrgetter的写法能正常运行,但Python3里None和int类型不能直接用<比较,就触发了TypeError。
下面给你两种实用的解决方案,你可以根据需求选择:
方法一:用Key函数替换None为可比较的极端值(推荐,更高效)
思路是把每个字段中的None替换成一个能和int正常比较的极端值,比如用float('-inf')让None排在所有数值前面,或者float('inf')让None排在最后。
注意:你的元素是字典类型,所以要用索引i['chromosome']而非属性访问i.chromosome,代码示例如下:
marker_list = sorted(marker_dict[experiment_id].values(), key=lambda i: ( i['chromosome'] if i['chromosome'] is not None else float('-inf'), i['linkageGroup'] if i['linkageGroup'] is not None else float('-inf'), i['positionCm'] if i['positionCm'] is not None else float('-inf') ))
如果希望None排在所有数值后面,只需要把float('-inf')替换成float('inf')即可。
方法二:用自定义比较函数(适合复杂排序逻辑)
如果你需要更灵活的比较规则(比如不同字段对None的排序优先级不同),可以用functools.cmp_to_key把自定义比较函数转换为排序key:
from functools import cmp_to_key def compare_markers(a, b): # 按chromosome -> linkageGroup -> positionCm的顺序依次比较 for field in ['chromosome', 'linkageGroup', 'positionCm']: val_a = a[field] val_b = b[field] # 两个都是None,继续比较下一个字段 if val_a is None and val_b is None: continue # a是None,让a排在前面 if val_a is None: return -1 # b是None,让b排在前面(即a排在后面) if val_b is None: return 1 # 都是数值,正常比较大小 if val_a < val_b: return -1 elif val_a > val_b: return 1 # 所有字段都相同,返回0 return 0 marker_list = sorted(marker_dict[experiment_id].values(), key=cmp_to_key(compare_markers))
这个方法可以针对每个字段单独定义None的排序规则,不过效率比方法一略低,适合复杂排序场景。
最后补充个小细节:你原来的代码里用了i.chromosome,但你的元素是字典类型,必须用i['chromosome']来访问对应值,这也是需要修正的地方哦。
内容的提问来源于stack exchange,提问作者Linwe
相关产品推荐
相关产品推荐

