如何通过函数传递的值对字典进行排序?

时间:2014-12-19 01:04:09

标签: python sorting dictionary lambda strptime

我有一个名为'times'的字典,它将键映射到表示时间的字符串值:

times = {'key1': '12.23', 'key2': '43:53.29', 'key3': '1:38:11.50r'}

字符串采用[小时]的形式:[分钟]:[秒]。[毫秒] [r] 每个字段都是可选的。 r是一个标志,它不依赖于任何其他值被填充,也不会影响排序。 [小时]要求[分钟]和下来,但[分钟]不需要[小时]出现。

我希望最终得到一个按照值的时间顺序排序的键列表。

我有以下内容:

standings = sorted(times, key=times.__getitem__)

但它只根据字符串值进行排序。我是python的新手,但如果我使用java,我可能会编写一个带有自定义compareTo()函数的Time类来使排序生效。

我可以编写一个函数,将字符串转换为以毫秒为单位的时间,然后根据它进行排序,但不知道如何在sorted()函数中使用'key ='进行排序。

3 个答案:

答案 0 :(得分:2)

import re
def as_list(time):
    """
    >>> as_list('1:38:11.50r')
    [1, 38, 11, 50]
    >>> as_list('2.23')
    [0, 0, 2, 23]
    """
    # Extract times and convert to integers
    times = [int(x) for x in re.split(r"[:.]", re.sub("[a-z]$", "", time))]
    # If needed pad from the left side with zeros and return
    return times if len(times) == 4 else [0] * (4 - len(times)) + times

[k for k, t in sorted(times.items(), key = lambda x: as_list(x[1]))]

或者更简洁的方式:

[key for _, key in sorted((as_list(v), k) for k, v in times.items())]

它的工作原理是因为Python中的列表或元组按字典顺序排序。我们假设你有以下列表:

>>> l = [[0, 1], [-1 , 2, 3], [4, 5], [0, -1]]

您可以在其上拨打sorted

>>> sorted(l)
[[-1, 2, 3], [0, -1], [0, 1], [4, 5]]

因此所有的魔力。

关于[0] * (4 - len(times)) + times,您可以在此处阅读更多内容:Create List of Single Item Repeated n Times in Python

长篇短篇some_list * some_integer会创建一个包含some_list重复some_integer次元素的列表。

答案 1 :(得分:0)

您可以执行以下操作:

standings = sorted(times.items(),key = lambda t : t[0])

它假定您要按字典的键排序。如果要按值排序,则将t [0]替换为t [1]。

请注意,我使用t [0]来获取对该键的引用,但在您的情况下,您将引用t [1],但您可能会将此值传递给将时间转换为字符串的函数格式很容易按字典顺序排序。例如,假设您有一个返回填充时间的time_format方法,然后用time_format(t [1])替换上面的t [0]。

答案 2 :(得分:0)

我认为你可以定义一个函数 to_decimal 来将时间字符串转换为小数进行比较,然后:

standings = sorted(times, key = lambda x : to_decimal(times[x]))
相关问题