簡體   English   中英

Python3中列表的自然排序

[英]Natural sorting of a list in Python3

我正在嘗試對列表進行排序:

[
    '[fc] EDW Ratio (10 degrees)', 
    ' [fc] EDW Ratio (45 degrees)', 
    ' [fc] EDW Ratio (60 degrees)', 
    ' [fc] EDW Ratio (25 degrees)', 
    ' [fc] EDW Ratio (20 degrees)', 
    ' [fc] EDW Ratio (30 degrees)', 
    ' [fc] EDW Ratio (15 degrees)', 
    ' [fc] EDW output factor (60 degrees)', 
    ' [fc] Quality index'
]

此處使用已接受答案的第一部分:

但是這個列表最終是這樣的:

[
    ' [fc] EDW Ratio (15 degrees)', 
    ' [fc] EDW Ratio (20 degrees)', 
    ' [fc] EDW Ratio (25 degrees)', 
    ' [fc] EDW Ratio (30 degrees)', 
    ' [fc] EDW Ratio (45 degrees)', 
    ' [fc] EDW Ratio (60 degrees)', 
    ' [fc] EDW output factor (60 degrees)', 
    ' [fc] Quality index', 
    '[fc] EDW Ratio (10 degrees)'
]

而我希望EDW 比率(10 度)在排序后位於列表的開頭(索引 position 0)。

如何才能做到這一點?

我的代碼包括以下內容:

#
# Method to define natural sorting used to sort lists
#
def atoi(text):
    return int(text) if text.isdigit() else text

def natural_keys(text):
    '''
    alist.sort(key=natural_keys) sorts in human order
    http://nedbatchelder.com/blog/200712/human_sorting.html
    (See Toothy's implementation in the comments)
    '''
    return [ atoi(c) for c in re.split(r'(\d+)', text) ]

    .
    .
    .


    tname_list = test_names.split(",") # this outputs the exact first (unsorted) list shown above

    tname_list.sort(key=natural_keys) # use human sorting defined above. This outputs the second list shown above.

您的代碼是正確的,但您的數據看起來不正確:所有條目都有一個前導空格,這意味着它們“在”您至少識別的那個之前,實際上沒有前導空格。

如果數據正常,我建議您修改代碼以忽略前導空格(檢查此: 如何刪除 Python 中的前導空格? )。

您需要修改natural_keys以僅將字符串的數字部分作為int返回。 您應該使用int()而不是atoi()進行轉換,后者返回字符的 ascii 代碼。

如果您的任何字符串包含多個數字,或者將數字放在字符串的開頭或結尾,您將遇到麻煩。 那是因為 Python 無法將intstr相互比較。 您的密鑰 function 應該以元組或列表的形式返回。

def atoi(text):
    return (int(text), '') if text.isdigit() else (math.nan, text)

math.nan很特別,因為它永遠不會比實際數字少。

我推薦使用natsort (完全公開,我是作者)。 您的數據也有點混亂,您需要刪除前導空格以規范所有條目。

from natsort import natsorted
data = [
    '[fc] EDW Ratio (10 degrees)', 
    ' [fc] EDW Ratio (45 degrees)', 
    ' [fc] EDW Ratio (60 degrees)', 
    ' [fc] EDW Ratio (25 degrees)', 
    ' [fc] EDW Ratio (20 degrees)', 
    ' [fc] EDW Ratio (30 degrees)', 
    ' [fc] EDW Ratio (15 degrees)', 
    ' [fc] EDW output factor (60 degrees)', 
    ' [fc] Quality index'
]
data_sorted = natsorted(data, key=lambda x: x.lstrip())

輸出

[
 '[fc] EDW Ratio (10 degrees)',
 ' [fc] EDW Ratio (15 degrees)',
 ' [fc] EDW Ratio (20 degrees)',
 ' [fc] EDW Ratio (25 degrees)',
 ' [fc] EDW Ratio (30 degrees)',
 ' [fc] EDW Ratio (45 degrees)',
 ' [fc] EDW Ratio (60 degrees)',
 ' [fc] EDW output factor (60 degrees)',
 ' [fc] Quality index',
]
import re

def get_numbers(texto):
    return int(re.findall(r'[0-9]+', texto)[0])
        
def sort_list(l):
    dicto = {}
    for i in l:
        dicto[get_numbers(i)] = i
    lista = []
    for i in sorted(list(dicto.keys())):
        lista.append(dicto[i])
    return lista

sort_list(frames)

請注意,它僅適用於第一組數字...“peter123jjj111”將僅考慮 123

暫無
暫無

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

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