2014-11-12 3 views
1

ОК, поэтому мне нужно выполнить сортировку списка путей к файлу в python 3.4. они должны быть в подпапках алфавитного порядка, но и их содержание первогоСортировка путей к файлу в python 3.4

примера вывод:

b/e/f.txt 
b/d.txt 
g/u.txt 
i/a/q.txt 
a.txt 
c.txt 
d.txt 

я пытался выяснить, как сделать это в течение последних нескольких часов с помощью Google, но не повезли

я боюсь, что я не имею доступ к интерпретатору v2 на данный момент, поэтому я не могу проверить правильность этого, но в v2 это будет выглядеть примерно так:

def FileComp(File1, File2): 
    if File1.count('/') == File2.count('/'): 
     return File1 < File2; 
    else 
     Same = 0; 
     FilePath1 = os.path.dirname(File1); 
     FilePath2 = os.path.dirname(File2); 
     FilePath1Len = len(FilePath1); 
     FilePath2Len = len(FilePath2); 
     while Same < FilePath1Len and Same < FilePath2Len and FilePath1[Same:Same] == FilePath2[Same:Same]: 
      Same += 1; 
     FilePath1 = FilePath1[Same:]; 
     FilePath2 = FilePath2[Same:]; 
     if len(FilePath1) == 0 or len(FilePath2) == 0: 
      return len(FilePath1) > len(FilePath2); 
     else 
      return File1 < File2; 

Files.sort(FileComp); 
+0

Как насчет разделения их на '/', а затем делать сортировку на основе наименьшего индекса? – Ranveer

ответ

4

Если вам необходимо иметь вложенные папки сортируются сначала, вам необходимо предоставить две вещи, чтобы сортировать по: флаг, если он не суб папка (True сортируется после False), а сам путь:

sorted(paths, key=lambda p: (os.path.sep not in p, p)) 

Для этого используется os.path.sep, чтобы определить, существует ли путь для подпапки или нет, поэтому вы сначала получаете подпапки.

So 'a.txt' преобразуется в (True, 'a.txt'), а 'b/d.txt' сортируется как (False, 'b/d.txt'); кортежи сортируются лексикографически с False отсортировано до True.

Если вам нужно глубже папки сортируется перед тем неглубокими папками, подсчитать количество разделителей и возврат, что в качестве отрицательного значения ; тем больше слэши «глубже» папку, и он будет отсортирован перед другими:

sorted(paths, key=lambda p: (-p.count(os.path.sep), p)) 

Демо:

>>> import os.path 
>>> paths = '''\ 
... b/e/f.txt 
... b/d.txt 
... a.txt 
... c.txt 
... '''.splitlines() 
>>> sorted(paths, key=lambda p: (os.path.sep not in p, p)) 
['b/d.txt', 'b/e/f.txt', 'a.txt', 'c.txt'] 
>>> import random 
>>> random.shuffle(paths) 
>>> sorted(paths, key=lambda p: (os.path.sep not in p, p)) 
['b/d.txt', 'b/e/f.txt', 'a.txt', 'c.txt'] 
>>> sorted(paths, key=lambda p: (-p.count(os.path.sep), p)) 
['b/e/f.txt', 'b/d.txt', 'a.txt', 'c.txt'] 
+0

Я боюсь, я не понимаю, что вы имеете в виду с первой частью, но вывод меня копирует/вставляет ваш код полностью случайно – khm

+0

@khm: он не является полностью случайным; он находится в отсортированном порядке с путями с косой чертой в них сперва, за ними следуют пути без косой черты. Я добавил еще один вариант для вас. –

+0

ОК, я, должно быть, испортил копию/вставил некоторые, потому что он переставал быть случайным, когда я делал это снова, но результат все еще не прав. Я действительно ценю усилие. – khm

1

Похоже, что порядок сортировки зависит от количества уровней вложенных папок в пути ,

Таким образом, при сортировке должен использоваться ключ, в котором учитывается это количество уровней подпапок. Самый простой способ - это функция lambda, которая даст нам кортеж подсчета уровня подпапки и имя самого пути. Счетчик должен быть отменен, так что пути с большим количеством подпапок будут первыми.

paths = ['a.txt', 'b/d.txt', 'b/e/f.txt', 'c.txt'] 
paths.sort(key=lambda x: (-x.count('/'), x)) 

Результат

['b/e/f.txt', 'b/d.txt', 'a.txt', 'c.txt'] 
+0

это близко, но не совсем правильно отображает фактический список, я обновил пример, чтобы лучше понять, что происходит. – khm

+0

Это довольно странная сортировка. Если вы не можете описать правила для этого, мы не сможем найти вычислимое решение. – Matthias

+0

как это странно? он находится в алфавитном порядке, но сначала появляются подпапки. – khm

Смежные вопросы