对列表进行排序不会产生正确的结果

时间:2014-04-02 07:56:04

标签: python sorting operator-keyword

python问题:

我正在运行一个sort函数来按日期对某些数据进行排序,并得到不正确的输出。我准备了一个我的代码的简短版本,其中包含一些示例数据以显示错误(完整代码无趣,完整的实际数据是专有的)。

以下是代码:

import operator

mylist = [['CustomerID_12345', 'TransactionID_1001', '12/31/2012'],
['CustomerID_12345', 'TransactionID_1002', '3/12/2013'],
['CustomerID_12345', 'TransactionID_1003', '1/7/2013'],
['CustomerID_12345', 'TransactionID_1004', '12/31/2012']]


sorted_list = sorted(mylist, key=operator.itemgetter(2))


print type(mylist)
print len(mylist)

for i in mylist:
    print i

print ""        # just for a line break for convenience

for i in sorted_list:
    print i

,输出为:

<type 'list'>
4
['CustomerID_12345', 'TransactionID_1001', '12/31/2012']
['CustomerID_12345', 'TransactionID_1002', '3/12/2013']
['CustomerID_12345', 'TransactionID_1003', '1/7/2013']
['CustomerID_12345', 'TransactionID_1004', '12/31/2012']

['CustomerID_12345', 'TransactionID_1003', '1/7/2013']
['CustomerID_12345', 'TransactionID_1001', '12/31/2012']
['CustomerID_12345', 'TransactionID_1004', '12/31/2012']
['CustomerID_12345', 'TransactionID_1002', '3/12/2013']

第一个块是原始数据,第二个是输出。由于我尝试按日期排序,因此很容易看出排序无法正常运行。

有人可以帮助解释错误并建议如何纠正错误吗? 在此先感谢:)

3 个答案:

答案 0 :(得分:5)

这是因为python将它们视为字符串而不是日期。

这是因为'1'小于'2',小于'3' 此外,'/'小于数字,因此存在问题。

而是尝试将它们作为日期进行比较,使用datetime模块。

以下是一个示例:

from datetime import datetime
your_date = datetime.strptime('1/1/2013', "%m/%d/%Y")
my_date = datetime.strptime('12/3/2011', "%m/%d/%Y")

print your_date > my_date
[Out]: True

答案 1 :(得分:5)

按日期排序:

from datetime import datetime

mylist = [['CustomerID_12345', 'TransactionID_1001', '12/31/2012'],
        ['CustomerID_12345', 'TransactionID_1002', '3/12/2013'],
        ['CustomerID_12345', 'TransactionID_1003', '1/7/2013'],
        ['CustomerID_12345', 'TransactionID_1004', '12/31/2012']]


sorted_list = sorted(mylist, key=lambda x: datetime.strptime(x[2],'%m/%d/%Y'))
for item in sorted_list:
    print item

或者您可以将日期存储为日期时间。如果它们是有充分理由的字符串,那么您可以先添加日期时间列:

for item in mylist:
    item.append(datetime.strptime(item[2], '%m/%d/%Y'))
sorted_list = sorted(mylist, key=lambda x: x[3])
for item in sorted_list: print item[:3]

答案 2 :(得分:2)

它正确排序。您将按照不按实际日期排序的愚蠢格式按日期字段进行排序。如果使用标准ISO格式(YYYY-MM-DD),它将按预期排序。此外,如果您使用用于日期的python数据结构,例如从datetime模块,它将按预期排序。

import datetime

mylist = [
    ['CustomerID_12345', 'TransactionID_1001', datetime.date(2012, 12, 13)],
    ['CustomerID_12345', 'TransactionID_1002', datetime.date(2013, 3, 12)],
    ...
]

或者,借用其他答案之一。如果您正在某处读取数据并希望将其从原始字符串格式转换为内部表示形式,这可以帮助您。

import datetime

mylist = [
    ['CustomerID_12345', 'TransactionID_1001',
        datetime.datetime.strptime('12/31/2012', '%m/%d/%Y').date()],
    ['CustomerID_12345', 'TransactionID_1002',
        datetime.datetime.strptime('3/12/2013', '%m/%d/%Y').date()],
    ...
]

或者,仅使用字符串......

mylist = [
    ['CustomerID_12345', 'TransactionID_1001', '2012-31-12'],
    ['CustomerID_12345', 'TransactionID_1002', '2013-03-12'],
    ...
]

如果您已经有一个类似问题的数组,您可以轻松转换它:

new_list = [f1, f2, datetime.datetime.strptime(f3, '%m/%d/%Y').date()
    for f1, f2, f3 in old_list]

只是旁注,M / D / YYYY(2014年4月2日)格式是有史以来最愚蠢的日期格式之一,只有M / D / YY(4/2/14)比这更糟糕。

最佳格式按降序排列单位,因为这是我们用于数字的方向。那些,当使用适当的零填充时,可以很容易地进行分类(2014-04-02),这就是为什么他们在计算机中找到了自己的位置,尤其是文件名。不太好的格式按升序大小排序单位,不尊重我们写下数字的方式,这个系统正在我的国家使用(今天是2.4.2014)。但是,不按大小按升序或降序对单位进行排序的混杂格式是几个世纪前我们应该杀死的东西。