2013-01-04 56 views
5

道歉,如果这已在其他地方回答;我试过搜索,但没有发现任何回答我的问题(或者我也有,但不明白)...Python - 对列表中的元素进行排序

我对Python(v2.6.2)相当新,并且有包含浮点值,看起来像下面列出的清单(除了满东西有2+万个条目为每个列表):

cat = [[152.123, 150.456, 151.789, ...], [4.123, 3.456, 1.789, ...], [20.123, 22.456, 21.789, ...]] 

现在我想要做什么列表排序的所有3按照第三列表元素的升序排列,例如,我得到:

cat_sorted = [[152.123, 151.789, 150.456, ...], [4.123, 1.789, 3.456, ...], [20.123, 21.789, 22.456, ...]] 

我试过了几件事情,但他们不给我我要找的东西(或者我错误地使用了它们)。有没有办法做我在找什么,如果是这样,最简单的&最快(考虑到我有3 x 200万条目)?有没有使用另一个列表排序一个列表的方法?

+0

只是想知道它是什么样的问题,蟒蛇真的适合这个吗?我还没有看到任何使用python执行这些数据量的任务的情况。 – Ixanezis

回答

8

这将是痛苦的,但使用默认的Python,你有两个选择:

  • 装饰第一和第二列表与enumerate(),然后使用该指数从3日列表,请参阅值进行排序,这些:

    cat_sorted = [ 
        [e for i, e in sorted(enumerate(cat[0]), key=lambda p: cat[2][p[0]])], 
        [e for i, e in sorted(enumerate(cat[1]), key=lambda p: cat[2][p[0]])], 
        sorted(cat[2]) 
    ] 
    

    尽管它可能帮助整理cat[2]就地而不是使用sorted();其他两个人无法绕过sorted()

  • zip()的三个列表,然后排序名单的这个新的列表的第三个元素,然后zip()再次回到原来的结构:

    from operator import itemgetter 
    cat_sorted = zip(*sorted(zip(*cat), key=itemgetter(2))) 
    

也不会有性能破坏者,而不是与数百万数字的纯Python列表。

+0

这是一个很好的解决方案! –

+0

一旦我明白OP的含义以及描述如何与示例输入和输出相匹配,我的脑海就会立即跳到您展示的“zip”方法。给出的问题描述表明,数据并没有真正组织起来;优雅地''拉链'围绕那。 –

+0

辉煌。使用zip命令的第二个解决方案完美地工作。谢谢您的帮助! :) – Shanagar

4

如果你愿意使用额外的图书馆,我建议Python Pandas。它有一个类似于R的data.frame的DataFrame对象,并接受构造函数中的列表列表,它将创建一个3列数据数组。然后,您可以轻松使用内置的pandas.DataFrame.sort函数按第三列进行排序(升序或降序)。

有很多简单的Python方法可以做到这一点,但考虑到问题的大小,在Pandas中使用优化函数是一种更好的方法。如果你需要从你的排序数据中获得任何汇总的统计数据,那么Pandas是一个不容忽视的数据。

+0

+1使用熊猫 - 这就是我正在写作过程中。其他答案是正确的,但对于如此庞大的数据集,像熊猫这样的图书馆就是您真正想要的。 – Iguananaut

2

我会采取的一般方法是做一个schwartzian transform整件事情。

将这三个列表一起压缩到一个元组列表中。

使用第三个元素作为键对元组进行排序。

遍历新排序的元组列表并重新填充三个列表。

1

完成的缘故,一个解决方案使用numpy的:

import numpy as np 

cat = [[152.123, 150.456, 151.789], 
     [4.123, 3.456, 1.789], 
     [20.123, 22.456, 21.789]] 

cat = np.array(cat) 
cat_sorted = cat[:, cat[2].argsort()] 

print cat_sorted 
[[ 152.123 151.789 150.456] 
[ 4.123 1.789 3.456] 
[ 20.123 21.789 22.456]] 
0

这里是另一种方法做它的基础上通过的Martijn Pieters的伟大的答案和pcalcao

def sort_by_last(ll): 
    """ 
     >>> sort_by_last([[10, 20, 30], [3, 2, 1]]) 
     [[30, 20, 10], [1, 2, 3]] 

     >>> sort_by_last([[10, 20, 30], [40, 50, 60], [3, 2, 1]]) 
     [[30, 20, 10], [60, 50, 40], [1, 2, 3]] 

     >>> sort_by_last([[10, 20, 30], [40, 50, 60], [1, 1, 1]]) 
     [[10, 20, 30], [40, 50, 60], [1, 1, 1]] 

     >>> sort_by_last([[10, 20, 30], [40, 50, 60], [1, 3, 1]]) 
     [[10, 30, 20], [40, 60, 50], [1, 1, 3]] 

     >>> sort_by_last([[152.123, 150.456, 151.789], [4.123, 3.456, 1.789], [20.123, 22.456, 21.789]]) 
     [[152.123, 151.789, 150.456], [4.123, 1.789, 3.456], [20.123, 21.789, 22.456]] 
    """ 
    return [sorted(x, key=lambda y: ll[-1][x.index(y)]) for x in ll] 

大弦有是一个文档字符串与doctest,测试函数将其复制到一个文件并运行它与 python -m doctest -v <file>

+0

这里的刺痛是'x.index()',它会使大列表的排序非常缓慢 –

0

在这里,keys是一个有序的索引列表。

keys = sorted(range(len(cat[2])), key=cat[2].__getitem__) 
cat_sorted = [[cat[i][k] for k in keys] for i in range(3)] 
相关问题