Не алфавитном порядке список операционной системы.listdir()
Я часто использую python для обработки каталогов данных. Недавно я заметил, что порядок списков по умолчанию изменился на что-то почти бессмысленное. Например, если я нахожусь в текущем каталоге, содержащем следующие подкаталоги: run01, run02,... run19, run20, а затем я создаю список из следующей команды:
dir = os.listdir(os.getcwd())
затем я обычно получаю список в таком порядке:
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
и так далее. Раньше порядок был буквенно-цифровой. Но это новое порядок остался со мной на некоторое время.
что определяет (отображаемый) порядок этих списков?
10 ответов:
Я думаю, что порядок связан с тем, как файлы индексируются в вашей файловой системе. Если вы действительно хотите, чтобы он придерживался некоторого порядка, вы всегда можете отсортировать список после получения файлов.
вы можете использовать встроенный
sortedфункция для сортировки строк, как вы хотите. Основываясь на том, что вы описываете,sorted(os.listdir(whatever_directory))кроме того, вы можете использовать
.sortметод список:lst = os.listdir(whatever_directory) lst.sort()Я думаю, что следует сделать трюк.
обратите внимание, что порядок, что
os.listdirполучает имена файлов, вероятно, полностью зависит от вашей файловой системы.
на документация:
ОС.listdir(путь)
возвращает список содержащий имена записей в каталог, заданный путем. список в произвольном порядке. Это не включите специальные записи '.' и '.. даже если они присутствуют в справочник.
ордер не может быть использован и является артефактом файловая система.
чтобы отсортировать результат, используйте
sorted(os.listdir(path)).
вероятно, это просто порядок, который C
readdir()возвращает. Попробуйте запустить эту программу с:#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.P. S. Только сейчас управлял этой и коде Python, и они оба дали мне отсортированный выходной, поэтому я не могу воспроизвести то, что вы видите.
Python по какой-то причине не поставляется со встроенным способом иметь естественная сортировка (что означает 1, 2, 10 вместо 1, 10, 2), так что вы должны написать его сами:
import re def sorted_aphanumeric(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_aphanumeric(os.listdir(...))
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.
Я обнаружил, что "сортировка" не всегда делает то, что я ожидал. например, у меня есть каталог, как показано ниже, и "сортировка" дает мне очень странный результат:
>>> 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']Кажется, он сначала сравнивает первый символ, если это самый большой, он будет последним.
предложенная комбинация ОС.listdir и отсортированный команды генерируют тот же результат, что и ls-l команда под Linux. Следующий пример подтверждает это предположение:
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$Итак, для того, кто хочет воспроизвести результат известного ls-l команда в его коде Python,отсортированный( ОС.listdir( реж ) ) работает довольно хорошо.
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'] 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))а для случая like
'run01.txt'или'run01.csv'вы можете сделать такойsorted(files, key=lambda x : int(os.path.splitext(x)[0]))
Эллиот ответ решает это отлично, но поскольку это комментарий, он остается незамеченным, поэтому с целью помочь кому-то, я повторяю его как решение.
использовать библиотеку natsort:
установить библиотеку с помощью следующей команды для Ubuntu и других версий Debian
Python 2
sudo pip install natsortPython 3
sudo pip3 install natsortинформация о том, как использовать эту библиотеку нашел здесь
Comments