簡體   English   中英

Python中包含路徑的自然排序列表

[英]Natural Sort of list containing paths in Python

我有一個列表paths_list ,其中包含特定文件夾的文件(圖像)的路徑。 例子:

['/home/username/images/s1/4.jpg', '/home/username/images/s1/7.jpg', 
'/home/username/images/s1/6.jpg', '/home/username/images/s1/3.jpg', 
'/home/username/images/s1/5.jpg', '/home/username/images/s1/10.jpg', 
'/home/username/images/s1/9.jpg', '/home/username/images/s1/1.jpg', 
'/home/username/images/s1/2.jpg', '/home/username/images/s1/12.jpg', 
'/home/username/images/s1/11.jpg', '/home/username/images/s1/8.jpg']

然后我想按順序排序: [/1.jpg ,2.jpg .....,/12.jpg]長度排序或按字母順序排序都無濟於事。 這里應該做什么?

您可以使用sortedlambda 對於排序標准,您可以使用os首先提取文件名(使用basename ),然后您可以只拆分文件名減去擴展名(使用splitext )。

最后轉換為int以便您按數字排序而不是按字典順序排序。

>>> import os
>>> l = ['/home/username/images/s1/4.jpg', '/home/username/images/s1/7.jpg', '/home/username/images/s1/6.jpg', '/home/username/images/s1/3.jpg', '/home/username/images/s1/5.jpg', '/home/username/images/s1/10.jpg', '/home/username/images/s1/9.jpg', '/home/username/images/s1/1.jpg', '/home/username/images/s1/2.jpg', '/home/username/images/s1/12.jpg', '/home/username/images/s1/11.jpg', '/home/username/images/s1/8.jpg']
>>> sorted(l, key=lambda i: int(os.path.splitext(os.path.basename(i))[0]))
['/home/username/images/s1/1.jpg',
 '/home/username/images/s1/2.jpg',
 '/home/username/images/s1/3.jpg',
 '/home/username/images/s1/4.jpg',
 '/home/username/images/s1/5.jpg',
 '/home/username/images/s1/6.jpg',
 '/home/username/images/s1/7.jpg',
 '/home/username/images/s1/8.jpg',
 '/home/username/images/s1/9.jpg',
 '/home/username/images/s1/10.jpg',
 '/home/username/images/s1/11.jpg',
 '/home/username/images/s1/12.jpg']

使用自然排序(請參閱此問題):對字符串進行排序時的代碼簡潔和良好做法。

from natsort import natsorted
l = ['/home/username/images/s1/4.jpg', '/home/username/images/s1/7.jpg', '/home/username/images/s1/6.jpg', '/home/username/images/s1/3.jpg', '/home/username/images/s1/5.jpg', '/home/username/images/s1/10.jpg', '/home/username/images/s1/9.jpg', '/home/username/images/s1/1.jpg', '/home/username/images/s1/2.jpg', '/home/username/images/s1/12.jpg', '/home/username/images/s1/11.jpg', '/home/username/images/s1/8.jpg']
natsorted(l)

['/home/username/images/s1/1.jpg',
'/home/username/images/s1/2.jpg',
'/home/username/images/s1/3.jpg',
'/home/username/images/s1/4.jpg',
'/home/username/images/s1/5.jpg',
'/home/username/images/s1/6.jpg',
'/home/username/images/s1/7.jpg',
'/home/username/images/s1/8.jpg',
'/home/username/images/s1/9.jpg',
'/home/username/images/s1/10.jpg',
'/home/username/images/s1/11.jpg',
'/home/username/images/s1/12.jpg']

自然排序基於您在計算機屏幕上閱讀內容的方式(按字母順序和數字順序),而不是計算機閱讀代碼的方式。

您可以在“/”上使用拆分,取最后一個元素,在“.”上拆分,取第一個,並將其轉換為 int:

l = ['/home/username/images/s1/4.jpg', '/home/username/images/s1/7.jpg', '/home/username/images/s1/6.jpg', '/home/username/images/s1/3.jpg', '/home/username/images/s1/5.jpg', '/home/username/images/s1/10.jpg', '/home/username/images/s1/9.jpg', '/home/username/images/s1/1.jpg', '/home/username/images/s1/2.jpg', '/home/username/images/s1/12.jpg', '/home/username/images/s1/11.jpg', '/home/username/images/s1/8.jpg']
sorted_list = sorted(l, key = lambda x: int(x.split("/")[-1].split(".")[0]))

輸出

['/home/username/images/s1/1.jpg',
 '/home/username/images/s1/2.jpg',
 '/home/username/images/s1/3.jpg',
 '/home/username/images/s1/4.jpg',
 '/home/username/images/s1/5.jpg',
 '/home/username/images/s1/6.jpg',
 '/home/username/images/s1/7.jpg',
 '/home/username/images/s1/8.jpg',
 '/home/username/images/s1/9.jpg',
 '/home/username/images/s1/10.jpg',
 '/home/username/images/s1/11.jpg',
 '/home/username/images/s1/12.jpg']

這里的其他答案很好。 但無論如何我想發表我的一些解釋

from os.path import basename,splitext
path_list = ['/home/username/images/s1/4.jpg', '/home/username/images/s1/7.jpg',
             '/home/username/images/s1/6.jpg', '/home/username/images/s1/3.jpg',
             '/home/username/images/s1/5.jpg', '/home/username/images/s1/10.jpg',
             '/home/username/images/s1/9.jpg', '/home/username/images/s1/1.jpg',
             '/home/username/images/s1/2.jpg', '/home/username/images/s1/12.jpg',
             '/home/username/images/s1/11.jpg', '/home/username/images/s1/8.jpg']

new_list = [splitext(basename(x))[0] for x in path_list]

fin_list = list(zip(path_list,new_list))

fin_list = [x[0] for x in sorted(fin_list,key=lambda x: int(x[1]))]

print(fin_list)

1) 創建一個只有文件名的列表。 1,2,..等等。

new_list = [splitext(basename(x))[0] for x in path_list]

注意:為什么 [0] ?? 因為每個splitext(basename(x))[0]的輸出是這樣的,

('1','.jpg') , ('4','.jpg')

所以[0] 0th索引只給了我們文件名!

2)將兩個迭代中的每個項目相互壓縮並創建一個列表。 所以這個列表有這樣的值,

fin_list = list(zip(path_list,new_list))
#output
('/home/username/images/s1/4.jpg','4.jpg')

3) [x[0] for x in sorted(fin_list,key=lambda x: int(x[1]))]

這個從fin_list注意的排序列表創建一個列表是這里的主要內容。 鍵將是元組中的第二項,即4,3,7,..等。 基於發生的排序。

最后你的輸出

['/home/username/images/s1/1.jpg', '/home/username/images/s1/2.jpg',
 '/home/username/images/s1/3.jpg', '/home/username/images/s1/4.jpg',
 '/home/username/images/s1/5.jpg', '/home/username/images/s1/6.jpg', 
'/home/username/images/s1/7.jpg', '/home/username/images/s1/8.jpg',
 '/home/username/images/s1/9.jpg', '/home/username/images/s1/10.jpg',
 '/home/username/images/s1/11.jpg', '/home/username/images/s1/12.jpg']

受@Cory Kramer 的回答啟發,您可以使用pathlib庫並獲得一種自然的路徑:

from pathlib import Path

a = ['/home/username/images/s1/4.jpg', 
     '/home/username/images/s1/7.jpg', 
     '/home/username/images/s1/6.jpg', 
     '/home/username/images/s1/3.jpg', 
     '/home/username/images/s1/5.jpg', 
     '/home/username/images/s1/10.jpg', 
     '/home/username/images/s1/9.jpg', 
     '/home/username/images/s1/1.jpg', 
     '/home/username/images/s1/2.jpg', 
     '/home/username/images/s1/12.jpg', 
     '/home/username/images/s1/11.jpg', 
     '/home/username/images/s1/8.jpg']

a = [Path(i) for i in a]
sorted_a = sorted(a, key=lambda i: int(i.stem))
sorted_a = [str(i) for i in a]

輸出:

['/home/username/images/s1/1.jpg',
 '/home/username/images/s1/2.jpg',
 '/home/username/images/s1/3.jpg',
 '/home/username/images/s1/4.jpg',
 '/home/username/images/s1/5.jpg',
 '/home/username/images/s1/6.jpg',
 '/home/username/images/s1/7.jpg',
 '/home/username/images/s1/8.jpg',
 '/home/username/images/s1/9.jpg',
 '/home/username/images/s1/10.jpg',
 '/home/username/images/s1/11.jpg',
 '/home/username/images/s1/12.jpg']

通常,使用pathlib有時可以提供比平面os.path更清晰的代碼表達式。

暫無
暫無

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

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