Python ไม่ว่าด้วยเหตุผลใดก็ตามไม่ได้มาพร้อมกับวิธีการเรียงลำดับตามธรรมชาติในตัว (หมายถึง 1, 2, 10 แทนที่จะเป็น 1, 10, 2) ดังนั้นคุณต้องเขียนเอง:
import re
def sorted_alphanumeric(data):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(data, key=alphanum_key)
ตอนนี้คุณสามารถใช้ฟังก์ชันนี้เพื่อจัดเรียงรายการ:
dirlist = sorted_alphanumeric(os.listdir(...))
ปัญหา:
ในกรณีที่คุณใช้ฟังก์ชันด้านบนเพื่อจัดเรียงสตริง (เช่นชื่อโฟลเดอร์) และต้องการให้เรียงลำดับเหมือน Windows Explorer จะทำงานไม่ถูกต้องในบางกรณีขอบ
ฟังก์ชันการเรียงลำดับนี้จะแสดงผลลัพธ์ที่ไม่ถูกต้องใน Windows หากคุณมีชื่อโฟลเดอร์ที่มีอักขระ 'พิเศษ' บางตัวอยู่ ตัวอย่างเช่นฟังก์ชันนี้จะจัดเรียง1, !1, !a, a
ในขณะที่ Windows Explorer จะเรียงลำดับ!1, 1, !a, a
จะจัดเรียง
ดังนั้นหากคุณต้องการเรียงลำดับเหมือนกับที่ Windows Explorer ทำใน Pythonคุณต้องใช้ฟังก์ชันStrCmpLogicalWในตัวของ Windows ผ่าน ctypes (แน่นอนว่าจะใช้ไม่ได้กับ Unix):
from ctypes import wintypes, windll
from functools import cmp_to_key
def winsort(data):
_StrCmpLogicalW = windll.Shlwapi.StrCmpLogicalW
_StrCmpLogicalW.argtypes = [wintypes.LPWSTR, wintypes.LPWSTR]
_StrCmpLogicalW.restype = wintypes.INT
cmp_fnc = lambda psz1, psz2: _StrCmpLogicalW(psz1, psz2)
return sorted(data, key=cmp_to_key(cmp_fnc))
ฟังก์ชันนี้ช้ากว่าเล็กน้อย sorted_alphanumeric()
ฟังก์ชั่นนี้จะช้ากว่าเล็กน้อย
โบนัส: winsort
ยังสามารถจัดเรียงเส้นทางแบบเต็มบน WindowsWindows
หรือโดยเฉพาะอย่างยิ่งถ้าคุณใช้ Unix คุณสามารถใช้natsort
ไลบรารี (pip install natsort
) เพื่อจัดเรียงตามเส้นทางแบบเต็มได้อย่างถูกต้อง (หมายถึงโฟลเดอร์ย่อยในตำแหน่งที่ถูกต้อง)
คุณสามารถใช้วิธีนี้เพื่อจัดเรียงเส้นทางแบบเต็ม:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
อย่าใช้สำหรับการเรียงลำดับชื่อโฟลเดอร์ตามปกติ (หรือสตริงโดยทั่วไป) เนื่องจากทำงานช้ากว่าsorted_alphanumeric()
ฟังก์ชันด้านบนเล็กน้อย
natsorted
ไลบรารีจะให้ผลลัพธ์ที่ไม่ถูกต้องหากคุณคาดว่าจะมีการเรียงลำดับของ Windows Explorer ดังนั้นใช้winsort()
สำหรับสิ่งนั้น