当字典被排序时,是否有一个键总是最后一个?

时间:2015-04-17 16:44:28

标签: python dictionary

我有一个包含许多键的字典,我想添加一个虚拟键,当字典排序时,它应该总是最后一个。并且排序不区分大小写。我在考虑使用字典'zyzzyva'中的最后一个单词。那会有用吗?如果我的密钥是目录路径,他们可以拥有/,。等等...

2 个答案:

答案 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键进行排序,但是这样会更难检测到如果它确实出现,可以解决。