dir = os.listdir(os.getcwd())
通常我会按照以下顺序得到一个列表:
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
等等。顺序过去是按字母数字顺序排列的。但是这个新的顺序现在已经保持了一段时间。
决定这些列表的(显示)顺序是什么?
dir = os.listdir(os.getcwd())
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
sorted
函数按照任意顺序对字符串进行排序。根据你所描述的。sorted(os.listdir(whatever_directory))
或者,你可以使用列表的.sort
方法:
lst = os.listdir(whatever_directory)
lst.sort()
os.listdir
获取文件名的顺序可能完全取决于您的文件系统。我认为顺序与文件系统中文件索引的方式有关。 如果您真的想让它遵循某种顺序,您可以在获取文件后对列表进行排序。
sorted(os.listdir(path))
。出于某些原因,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资源管理器的方式进行排序,那么在某些边缘情况下它将不能正常工作。
如果您在Windows上拥有包含某些“特殊”字符的文件夹名称,则此排序函数将返回错误的结果。例如,此函数将对1,!1,!a,a
进行排序,而Windows资源管理器将对!1,1,!a,a
进行排序。
因此,如果您想要在Python中像Windows资源管理器一样精确排序,则必须通过ctypes使用Windows内置函数StrCmpLogicalW(当然这在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
还可以在Windows上对完整路径排序。
或者,如果您使用Unix系统,可以使用natsort
库(pip install natsort
)以正确的方式按完整路径排序(意味着子文件夹位于正确位置)。
您可以像这样使用它来对完整路径进行排序:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
从版本7.1.0开始,natsort支持os_sorted
,它在内部使用之前提到的Windows API或Linux排序,应该替代natsorted()
使用。
print( sorted_aphanumeric(["1", "10", "2", "foo_10", "foo_8"]) )
-> ['1', '2', '10', 'foo_8', 'foo_10']
。正如预期的那样。 - user136036natsorted
一直存在一个长期未解决的问题,即实现Windows Explorer匹配功能。也许您应该贡献一个解决方案?https://github.com/SethMMorton/natsort/issues/41 - SethMMorton我认为默认情况下,顺序是由ASCII值确定的。解决这个问题的方法是这样的:
dir = sorted(os.listdir(os.getcwd()), key=len)
使用 natsort
库:
在 Ubuntu 和其他 Debian 版本中使用以下命令安装库:
Python 2
sudo pip install natsort
Python 3
->Python 3
sudo pip3 install natsort
如何使用此库的详细信息可在此处找到
from natsort import natsorted
files = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08']
natsorted(files)
[out]:
['run01', 'run08', 'run11', 'run12', 'run13', 'run14', 'run18']
sorted()
更准确!谢谢 - Farid Alijaniaaa = ['row_163.pkl', 'row_394.pkl', 'row_679.pkl', 'row_202.pkl', 'row_1449.pkl', 'row_247.pkl', 'row_1353.pkl', 'row_749.pkl', 'row_1293.pkl', 'row_1304.pkl', 'row_78.pkl', 'row_532.pkl', 'row_9.pkl', 'row_1435.pkl']
sorted(aaa, key=lambda x: int(os.path.splitext(x.split('_')[1])[0]))
针对我的需求,我有以下情况:row_163.pkl
,使用os.path.splitext('row_163.pkl')
会将其拆分为('row_163', '.pkl')
,因此需要基于下划线进行拆分。
但是对于您的需求,您可以做如下操作:
sorted(aa, key = lambda x: (int(re.sub('\D','',x)),x))
在哪里
aa = ['run01', 'run08', 'run11', 'run12', 'run13', 'run14', 'run18']
同时,如果您需要检索目录,则可以执行以下操作:sorted(os.listdir(path))
对于像'run01.txt'
或'run01.csv'
这样的情况,您可以按照以下方式操作:
sorted(files, key=lambda x : int(os.path.splitext(x)[0]))
很可能只是C语言中readdir()
返回的顺序问题。尝试运行以下C程序:
#include <dirent.h>
#include <stdio.h>
int main(void){
DIR *dirp;
struct dirent* de;
dirp = opendir(".");
while(de = readdir(dirp)) // Yes, one '='.
printf("%s\n", de->d_name);
closedir(dirp);
return 0;
}
gcc -o foo foo.c
。来自文档:
列表是任意排序的,即使目录中有'.'和'..'这两个特殊条目,它们也不会出现在列表中。
这意味着顺序可能与操作系统/文件系统有关,没有特别有意义的顺序,因此不能保证具体顺序。正如许多答案提到的那样:如果需要,可以对检索到的列表进行排序。
谢谢 :)
os.listdir
和sorted
命令的组合,可以生成与Linux下的ls -l
命令相同的结果。以下示例验证了这个假设:user@user-PC:/tmp/test$ touch 3a 4a 5a b c d1 d2 d3 k l p0 p1 p3 q 410a 409a 408a 407a
user@user-PC:/tmp/test$ ls -l
total 0
-rw-rw-r-- 1 user user 0 Feb 15 10:31 3a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 407a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 408a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 409a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 410a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 4a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 5a
-rw-rw-r-- 1 user user 0 Feb 15 10:31 b
-rw-rw-r-- 1 user user 0 Feb 15 10:31 c
-rw-rw-r-- 1 user user 0 Feb 15 10:31 d1
-rw-rw-r-- 1 user user 0 Feb 15 10:31 d2
-rw-rw-r-- 1 user user 0 Feb 15 10:31 d3
-rw-rw-r-- 1 user user 0 Feb 15 10:31 k
-rw-rw-r-- 1 user user 0 Feb 15 10:31 l
-rw-rw-r-- 1 user user 0 Feb 15 10:31 p0
-rw-rw-r-- 1 user user 0 Feb 15 10:31 p1
-rw-rw-r-- 1 user user 0 Feb 15 10:31 p3
-rw-rw-r-- 1 user user 0 Feb 15 10:31 q
user@user-PC:/tmp/test$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.listdir( './' )
['d3', 'k', 'p1', 'b', '410a', '5a', 'l', 'p0', '407a', '409a', '408a', 'd2', '4a', 'p3', '3a', 'q', 'c', 'd1']
>>> sorted( os.listdir( './' ) )
['3a', '407a', '408a', '409a', '410a', '4a', '5a', 'b', 'c', 'd1', 'd2', 'd3', 'k', 'l', 'p0', 'p1', 'p3', 'q']
>>> exit()
user@user-PC:/tmp/test$
所以,对于想要在python代码中复制著名的ls -l
命令结果的人来说,sorted( os.listdir( DIR ) )
非常有效。
sorted(listdir)
对我起作用。listdir.sort()
出现了TypeError: 'NoneType' object is not iterable的错误提示。 - paul_hlistdir.sort()
不适用于像for i in listdir.sort()
这样的语句,因为list.sort()
方法会原地改变列表中项目的顺序,这意味着处理列表本身但不返回任何东西,只返回None
。所以你需要使用a_list = listdir('some_path'); a_list.sort()
然后执行for i in a_list
。 - Sean_Syuesorted
可以在一行内完成,没问题吧? - mgilson