根据子集

时间:2016-03-31 02:41:40

标签: python list

我正在处理文件名列表。没有重复项,列表已排序。

列表可以分组为子集。名称中带有_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的子列表。这里,子列表具有任意长度。其他人使用&#34; separator&#34;分隔原始(平面)列表中的子列表,并在制作列表列表时最终被抛出。在这个意义上我没有分隔符,因为我不想丢弃原始列表中的任何项目。

任何人都可以建议一个比我上面更好的方法吗?

3 个答案:

答案 0 :(得分: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])]

答案 1 :(得分: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

答案 2 :(得分: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)