Python 基于时间对字典列表值进行排序

Python 基于时间对字典列表值进行排序,python,list,sorting,date,dictionary,Python,List,Sorting,Date,Dictionary,我对python非常陌生(几周前就开始使用python了),我在数据结构方面遇到了一些麻烦。到目前为止,我所做的是从一个.txt文件中逐行提取文本,并将它们存储到一个字典中,例如,键为animal database = { 'dog': ['apple', 'dog', '2012-06-12-08-12-59'], 'cat': [ ['orange', 'cat', '2012-06-11-18-33-12'], ['blue', 'cat',

我对python非常陌生(几周前就开始使用python了),我在数据结构方面遇到了一些麻烦。到目前为止,我所做的是从一个.txt文件中逐行提取文本,并将它们存储到一个字典中,例如,键为animal

database = {
    'dog': ['apple', 'dog', '2012-06-12-08-12-59'],
    'cat': [
        ['orange', 'cat', '2012-06-11-18-33-12'],
        ['blue', 'cat', '2012-06-13-03-23-48']
    ],
    'frog': ['kiwi', 'frog', '2012-06-12-17-12-44'],
    'cow': [
        ['pear', 'ant', '2012-06-12-14-02-30'],
        ['plum', 'cow', '2012-06-12-23-27-14']
    ]
} 

# year-month-day-hour-min-sec                                       
这样,当我把字典打印出来时,它会按动物类型打印出来,最新的日期会先打印出来

按时间对这些数据进行排序的最佳方式是什么?我使用的是python 2.7。我想的是

对于每个键:

抓取列表(或列表列表)-->获取第三个条目-->
'-'。拆分它,-->然后尝试排序(参数)


我只是不知道该怎么做

浏览字典中的元素。对于每个值,在列表列表上运行
sorted
,并告诉排序算法使用列表的第三个字段作为“key”元素。此关键元素用于将值与列表中的其他元素进行比较,以确定排序顺序。要告诉列表中要排序的元素,请使用
操作符.itemgetter
指定第三个元素

由于您的时间戳是严格构造的,并且时间戳中的每个字符都比下一个字符在时间上更重要,因此您可以像字符串一样自然地对它们进行排序—您不需要将它们转换为时间

# Dictionary stored in d
from operator import itemgetter
# Iterate over the elements of the dictionary; below, by
# calling items(), k gets the key value of an entry and 
# v gets the value of that entry
for k,v in d.items():
    if v and isinstance(v[0], list):
        v.sort(key=itemgetter(2)) # Start with 0, so third element is 2

如果您的日期都是
年-月-日-小时-分钟-秒
2012-06-12-23-27-14
,我认为您的拆分步骤是不必要的,只需将它们作为字符串进行比较即可

>>> '2012-06-12-23-27-14' > '2012-06-12-14-02-30'                              
True 

首先,您可能希望dict中的每个键、值项都是类似的类型。目前,其中一些(例如:database['dog'])是一个字符串列表(一行),一些(例如:database['cat'])是一个行列表。如果您将它们全部转换为行列表格式(即使行列表中只有一项),这将更容易

然后,一种(旧的)方法是为这些行创建一个比较函数。这将是很容易的,因为你的日期已经在一个直接(字符串)可比的格式。要比较两行,您需要比较其中的第三个(第二个索引)项:

def compare_line_by_date(x,y):
    return cmp(x[2],y[2])
最后,您可以通过告诉
sorted
内置使用compare\u line\u by\u date函数来对特定键的行进行排序:

sorted(database['cat'],compare_line_by_date)
上述方法适用于任意复杂的比较/排序函数(但速度较慢,并将在python 3中消失)。还有其他方法可以进行特定排序,例如使用排序的
参数:

def key_for_line(line):
    return line[2]

sorted(database['cat'],key=key_for_line)
使用键进行排序要比cmp快得多,因为键函数只需要在列表中的每个要排序的项目上运行一次,而不是每次比较列表中的项目(通常比列表中的项目数频繁得多)。键的概念基本上是将每个列表项浓缩成可以自然比较的东西,比如字符串或数字。在上面的示例中,我们将行简化为日期,然后进行比较


免责声明:我没有测试这个答案中的任何代码。。。但它应该是有效的

那个数据结构被破坏了。希望我的修正就是你的意思?也不要使用
dict
作为名称。这是一个内置的日期不需要转换-他们会自然排序,因为他们是感谢jdi!是的,你的编辑正是我想要的。谢谢你的修复。现在,它真的是像一些动物只有一个单级列表,而一些动物有嵌套列表那样的可变结构吗?@jdi提出了一个很好的观点-这是你的示例中的疏忽还是反映了你的实际数据?你介意解释一下k,v是什么吗。我见过一些与此类似的代码,但从来没有解释过。@user1443368我已经修改了我的答案来详细说明一下。这个解决方案有一个问题。它不考虑单个列表,并打乱了它们的顺序:
狗:['2012-06-12-08-12-59','dog','apple']
@jdi哎呀,我没有注意到有些值不是嵌套列表。敏锐的观察。快速修复:只需在排序之前添加一个测试:
如果v和isinstance(v[0],列表):
噢,哇,这很有趣。我不知道你可以用字符串来判断大于或小于。我要指出的是,使用cmp函数比使用键函数慢得多。请不要告诉人们使用
cmp
sorted
。它已被弃用一年reason@gnibbler您是说在底层比较函数中不使用cmp参数(我认为这是必需的)还是cmp?它在2.7中被弃用了吗?医生没有提到这点。@jdi是的,你说得对。我想主要的事情是向OP展示一种生成任意比较函数的方法,而不仅仅是针对特定情况的比较函数,OP仍在学习python。为任意函数使用键参数需要一个额外的逻辑步骤,这可能会引出太多的答案。@chees:注意文档引用了,并且在python 3.x中删除了它。至于教任意cmp函数,我认为现在的首选是在自定义类上定义比较运算符函数,而不是旧的cmp函数。因此,在这种情况下,将其作为一个选项来表示并没有真正的帮助。