2

Say I want to create a sorted dictionary (using OrderedDict), based on a rather complex operation on the values:

sorting_function = lambda x: x[1][0]
my_dictionary    = OrderedDict(sorted(my_dictionary.items(), key=sorting_function))

The problem with the code above is that, as I have it now, for some keys, my dictionary holds the value None, so the lambda operator throws an exception.

I would like these entries to be placed last in my dictionary, but I don't know how to modify my lambda function to handle exceptions. Do I need to resort to a full fledged function for this? Any thoughts?

Update:

To clarify, x[1][0] returns a string in my dictionary, when the entry is not None

4

4 回答 4

2
lambda x: None if x[1] is None else x[1][0]

这实际上将Nones 放在首位,因为None它似乎比什么都少。嗯,这很有趣。

在 Python 3 中,默认情况下您不能比较不兼容类型的对象。因此,为了面向未来,您应该替换一个可以与任何类型进行比较的值x[1][0]。当然,这种方法也适用于 Python 2.x。例如,如果它是数字,您可以使用:

lambda x: float("+inf") if x[1] is None else x[1][0]

这将使None值全部排序到最后。

float("+inf")对每个值进行评估None并不是最佳性能;如果这是一个瓶颈,只需定义一次并在您的 lambda 中使用它:

posinf = float("+inf")
lambda x: posinf if x[1] is None else x[1][0]

如果碰巧这float("+inf")可能是您的数据的有效值,那么您可能需要一个特殊的类,它总是比较大于其他任何东西:

class Maximus(object):
    "Object that is greater than any other object (but equal to itself)."
    __le__ = __eq__ = lambda self, other: isinstance(other, type(self))
    __ne__ = __gt__ = lambda self, other: not isinstance(other, type(self))
    __lt__ = lambda self, other: False      
    __ge__ = lambda self, other: True
    __str__  = lambda self: "I am the greatest!"
    __repr__ = lambda self: "Maximus()"

maximus = Maximus()

lambda x: maximus if x[1] is None else x[1][0]

(我相信只有__lt__并且__eq__需要实现排序才能工作,但是Maximus有完整的比较方法。)

于 2013-09-16T21:56:23.470 回答
1
def sort_key(item):
    key, value = item
    return (value is None, value[0] if value is not None else None)

如果你真的想的话,你可以把它塞进一个 lambda,但我不推荐它。

于 2013-09-16T21:57:57.873 回答
1

您可以考虑“请求许可”:lambda x: x[1][0] if x is not None else None.

但是,如果您预见到您的函数会变得更加复杂,您可能会考虑将其设为一个完整的函数:

def mySortingFunction(x):
    # do stuff

my_dictionary = OrderedDict(sorted(my_dictionary.items(), key=mySortingFunction)
于 2013-09-16T21:58:14.080 回答
0

您可以尝试在 lambda 中使用三元运算符:

lambda x:x[1][0] if x[1][0] else 0
于 2013-09-16T21:58:46.073 回答