簡體   English   中英

Python - 在列表列表中對元素進行排序

[英]Python - Sorting elements in a list of lists

如果在別處得到回答,請道歉; 我試過搜索,但沒有找到任何能回答我問題的東西(或許我有,但不明白)......

我是Python的新手(v2.6.2)並且有一個包含浮點值的列表列表,看起來類似於以下內容(除了完整的東西每個列表有超過200萬個條目):

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×2百萬條款)? 有沒有辦法用另一個列表排序一個列表?

這將是痛苦的,但使用默認的python你有2個選擇:

  • 使用enumerate()裝飾第一個和第二個列表,然后使用索引對這些列表進行排序以引用第三個列表中的值:

     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() ; 你不能使用sorted()來解決其他兩個問題。

  • zip()將三個列表放在一起,然后對這個新列表列表的第三個元素進行排序,然后再次使用zip()返回到原始結構:

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

兩者都不是性能破壞者,也不是數百萬個數字的普通python列表。

如果您願意使用額外的庫,我建議使用Python Pandas 它有一個類似於R的data.frame的DataFrame對象,並接受構造函數中的列表列表,這將創建一個3列數據數組。 然后,您可以輕松使用內置的pandas.DataFrame.sort函數按第三列(升序或降序)進行排序。

有許多簡單的Python方法可以做到這一點,但考慮到問題的大小,使用Pandas中的優化函數是一種更好的方法。 如果您需要從排序數據中獲得任何類型的匯總統計數據,那么Pandas就是一個明智的選擇。

我將采取的一般方法是對整個事情進行schwartzian變換

將三個列表一起壓縮成元組列表。

使用第三個元素作為鍵對元組進行排序。

迭代新排序的元組列表並再次填寫三個列表。

為了完成,使用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]]

基於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的docstring,用於測試函數將其復制到文件並使用python -m doctest -v <file>運行它

這里, 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)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM