Python中os.listdir()的非数字列表顺序

我经常使用python来处理数据目录。 最近,我已经注意到列表的默认顺序已经变成几乎荒谬的东西。 例如,如果我在包含以下子目录的当前目录中:run01,run02,… run19,run20,然后从以下命令生成一个列表:

dir = os.listdir(os.getcwd()) 

那么我通常会按照这个顺序得到一个列表:

 dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ] 

等等。 订单过去是字母数字。 但是这个新命令现在还在我身边。

什么是确定这些列表(显示)的顺序? 这里有一些规则吗? 这是我忘记改变的一些设置的结果吗?

编辑:谢谢大家的build议,有没有人知道在哪里/如何确定这个文件的顺序? 我已经确定这只发生在MacFUSE安装的驱动器上。

我认为这个命令与文件在你的FileSystem上的索引方式有关。 如果你真的想使它坚持一定的顺序,你总是可以在获取文件后对列表进行sorting。

你可以使用内build的sorted函数来sortingstring,但是你想要的。 根据你所描述的,

 sorted(os.listdir(whatever_directory)) 

或者,您可以使用列表的.sort方法:

 lst = os.listdir(whatever_directory) lst.sort() 

我认为应该做的伎俩。

请注意, os.listdir获取文件名的顺序可能完全取决于您的文件系统。

根据文档 :

os.listdir(path)

返回一个列表,其中包含由path指定的目录中的条目的名称。 该列表以任意顺序 。 它不包括特殊条目。“ 和“..”,即使它们存在于目录中。

顺序不能被依赖,是文件系统的人造物。

要sorting的结果,使用sorted(os.listdir(path))

这可能只是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

PS只是运行这个和你的Python代码,他们都给了我sorting的输出,所以我不能再现你所看到的。

 In [6]: os.listdir? Type: builtin_function_or_method String Form:<built-in function listdir> Docstring: listdir(path) -> list_of_strings Return a list containing the names of the entries in the directory. path: path of directory to list The list is in **arbitrary order**. It does not include the special entries '.' and '..' even if they are present in the directory. 

build议的os.listdirsorted命令的组合与Linux下的ls -l命令产生相同的结果。 以下示例validation了这个假设:

 user@user-PC:/tmp/test$ touch 3a 4a 5a bc d1 d2 d3 kl 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命令结果的人来说, sorting(os.listdir(DIR))工作得很好。

我发现“sorting”并不总是做我所期望的。 例如,我有一个目录如下,“sorting”给了我一个非常奇怪的结果:

 >>> os.listdir(pathon) ['2', '3', '4', '5', '403', '404', '407', '408', '410', '411', '412', '413', '414', '415', '416', '472'] >>> sorted([ f for f in os.listdir(pathon)]) ['2', '3', '4', '403', '404', '407', '408', '410', '411', '412', '413', '414', '415', '416', '472', '5'] 

看来它比较了第一个字符,如果这是最大的,这将是最后一个。

aaa = ['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']
(如果我的要求我有这样的情况像row_163.pkl这里操作系统(OS) .path.splitext('row_163.pkl')会把它分成('row_163','.pkl'),所以需要根据'_'来分割它。

但如果你的要求,你可以做类似的事情

(aa,key = lambda x:(int(re.sub('\ D','',x)),x))

其中aa = ['run01','run08','run11','run12','run13','run14','run18'],并且还用于检索目录,可以进行sorting(os.listdir(path))

对于像“run01.txt”或“run01.csv”的情况,你可以这样做

sort(files,key = lambda x:int(os.path.splitext(x)[0]))