我有一个包含许多键的字典,我想添加一个虚拟键,当字典排序时,它应该总是最后一个。并且排序不区分大小写。我在考虑使用字典'zyzzyva'
中的最后一个单词。那会有用吗?如果我的密钥是目录路径,他们可以拥有/,。等等...
答案 0 :(得分:9)
您可以创建一个ad-hoc对象,该对象在排序时始终是最后一个:
import functools
@functools.total_ordering
class Last(object):
def __eq__(self, other):
return False
def __lt__(self, other):
return False
这是一个用法示例:
>>> sorted([Last(), 'c', 'a', 'b'])
['a', 'b', 'c', <__main__.Last object at 0x7f8db518d2e8>]
如果您需要字符串,请考虑使用'\xff'
。如果您的所有密钥都是字母数字(在某种意义上它们由字母A-Z和数字0-9组成),那么就不会出现大于'\xff'
的项目。
>>> sorted(['\xff', 'c', 'a', 'b'])
['a', 'b', 'c', 'ÿ']
请注意,在某些编码(包括UTF-8)中,使用'\xff'
字符。
如果您使用的是Unicode字符串(或使用的是Python 3),那么u'\uffff'
可能是'\xff'
的替代品。
答案 1 :(得分:2)
我在考虑使用词典中的最后一个词&#39; zyzzyva&#39;。那会有用吗?
嗯,这取决于您的数据。你的钥匙都是英文字典吗?然后它会工作。但是如果你的键可以是任意类似字的字符串,那么你可以拥有'zzz'
。或者如果它们可以是非英语单词,您可能会有一个以'z'
之后的字母开头的单词。如果他们甚至不是单词,他们可能会有任何字母之后的字符。
既然你说你的密钥可能是目录路径,那么它们显然不是全部英文单词。
一种可能性是创建一个类,其成员比任何字符串都要大:
@functools.total_ordering
class StringInfinity(str):
def __new__(cls):
return str.__new__(StringInfinity, 'I am the biggest string')
def __lt__(self, other): return False
def __eq__(self, other): return isinstance(other, StringInfinity)
>>> s = StringInfinity()
>>> s
'I am the biggest string'
>>> s > 'zzz'
True
请注意,有些边缘情况会导致str
子类出现问题,但我不认为您可能需要担心。 * < / p>
*一些C扩展模块希望str
完全一个str
,而不是子类。如果您将所有密钥都传递给此类模块,那么您将获得TypeError
。这种情况很少见,易于检测,并且易于解决(例如,仅通过str(key)
而不是key
)。更严重的是,可以想象C扩展模块可以假设任何str
都是str
,而不检查它,比如直接比较缓冲区。哪个会默默地做错事。我不知道是否有人写过这样的模块,而且我不知道你是否关心在原始调用之外进行比较以对dict键进行排序,但是这样会更难检测到如果它确实出现,可以解决。