2016-03-31 4 views
0

Я работаю со списком имен файлов. Нет дубликатов, и список сортируется.Изменить список в список списков в зависимости от местоположения подмножества

Список может быть сгруппирован в подмножества. Файлы с номером _0001 указывают на начало нового подмножества. Тогда _0002 является вторым элементом в подмножестве и так далее. Я хотел бы преобразовать этот плоский список в иерархический список списков.

Вот пример оригинального, плоского списка:

['Log_03-22-2016_12-06-18_GMT_0001.log', 
'Log_03-22-2016_12-10-41_GMT_0002.log', 
'Log_03-22-2016_12-11-56_GMT_0003.log', 
'Log_03-22-2016_12-13-12_GMT_0004.log', 
'Log_03-22-2016_12-14-27_GMT_0005.log', 
'Log_03-22-2016_12-15-43_GMT_0006.log', 
'Log_03-22-2016_12-16-58_GMT_0007.log', 
'Log_03-23-2016_09-08-57_GMT_0001.log', 
'Log_03-23-2016_09-13-24_GMT_0002.log', 
'Log_03-23-2016_09-14-26_GMT_0003.log', 
'Log_03-23-2016_09-15-27_GMT_0004.log', 
'Log_03-23-2016_11-17-57_GMT_0001.log', 
'Log_03-23-2016_11-19-21_GMT_0002.log'] 

Я хотел бы, чтобы нарезать это в списки подмножеств, используя присутствие _0001 обнаружить начало нового подмножества. Затем верните список всех списков подмножеств. Вот пример вывода, используя приведенный выше вход:

[['Log_03-22-2016_12-06-18_GMT_0001.log', 
    'Log_03-22-2016_12-10-41_GMT_0002.log', 
    'Log_03-22-2016_12-11-56_GMT_0003.log', 
    'Log_03-22-2016_12-13-12_GMT_0004.log', 
    'Log_03-22-2016_12-14-27_GMT_0005.log', 
    'Log_03-22-2016_12-15-43_GMT_0006.log', 
    'Log_03-22-2016_12-16-58_GMT_0007.log'], 
['Log_03-23-2016_09-08-57_GMT_0001.log', 
    'Log_03-23-2016_09-13-24_GMT_0002.log', 
    'Log_03-23-2016_09-14-26_GMT_0003.log', 
    'Log_03-23-2016_09-15-27_GMT_0004.log'], 
['Log_03-23-2016_11-17-57_GMT_0001.log', 
    'Log_03-23-2016_11-19-21_GMT_0002.log']] 

Вот это текущее решение, которое у меня есть. Похоже, что там должно быть более элегантный и Pythonic способ сделать это:

import glob 

first_log_indicator = '_0001' 

log_files = sorted(glob.glob('Log_*_GMT_*.log')) 

first_logs = [s for s in log_files if first_log_indicator in s] 

LofL = [] 

if len(first_logs) > 1: 
    for fl_idx, fl_name in enumerate(first_logs): 
     start_slice = log_files.index(fl_name) 
     if fl_idx + 1 < len(first_logs): 
      stop_slice = log_files.index(first_logs[fl_idx+1]) 
      LofL.append(log_files[start_slice:stop_slice]) 
     else: 
      LofL.append(log_files[start_slice:]) 
else: 
    LofL.append(log_files) 

Я посмотрел в itertools, и пока я правда не знаком с этим модулем, я ничего не видел, что совсем это сделал.

Ближайшие вопросы, которые я мог найти на SO, имели переписчики fixed length. Здесь подсписки имеют произвольную длину. Другие использовали наличие «separator», чтобы разграничить подсписки в исходном (плоском) списке и которые в конечном итоге будут выбрасываться при составлении списка списков. У меня нет разделителя в этом смысле, так как я не хочу выбрасывать все элементы в исходном списке.

Может ли кто-нибудь предложить лучший подход, чем то, что у меня выше?

+1

Я думаю, это то, что вы ищете: http://stackoverflow.com/ вопросы/15357830/питон-spliting-а-список на основе-на-разделитель-слово. За исключением того, что вам нужно применить проверку окончания. – alecxe

ответ

2

Вы можете получить индексы первого в каждой серии, а затем разделить список следующим образом:

firsts = [i for i, v in enumerate(log_files) if '_0001' in v] 
list_of_lists = [log_files[i:j] for i, j in zip(firsts, firsts[1:] + [None])] 
+0

Это хорошо, но технически, если список начинается с чего-то другого, кроме «0001», некоторые значения могут быть отброшены. –

0

Я думаю @sp. имеет элегантное решение. Вот синий метод воротника:

lst = ['Log_03-22-2016_12-06-18_GMT_0001.log', 
'Log_03-22-2016_12-10-41_GMT_0002.log', 
'Log_03-22-2016_12-11-56_GMT_0003.log', 
'Log_03-22-2016_12-13-12_GMT_0004.log', 
'Log_03-22-2016_12-14-27_GMT_0005.log', 
'Log_03-22-2016_12-15-43_GMT_0006.log', 
'Log_03-22-2016_12-16-58_GMT_0007.log', 
'Log_03-23-2016_09-08-57_GMT_0001.log', 
'Log_03-23-2016_09-13-24_GMT_0002.log', 
'Log_03-23-2016_09-14-26_GMT_0003.log', 
'Log_03-23-2016_09-15-27_GMT_0004.log', 
'Log_03-23-2016_11-17-57_GMT_0001.log', 
'Log_03-23-2016_11-19-21_GMT_0002.log'] 

lsts = [] 
buf = [lst[0]] 
for l in lst[1:]: 
    if l[-8:-4] == '0001': 
     lsts.append(buf) 
     buf = [l] 
    else: 
     buf.append(l) 
lsts.append(buf) 
1

Если элементы всегда держать эту картину, я бы сделать что-то вроде:

prepared_data = ((element, element.split('.')[0].split('_')[-1]) for element in log_files) 
final_logs = [] 
for element in prepared_data: 
    if element[1] == '0001': 
     final_logs.append([element[0]]) 
    else: 
     final_logs[-1].append(element[0]) 
print final_logs 
Смежные вопросы