【问题标题】:How to group similarly named elements in a list into tuples in python?python - 如何将列表中类似命名的元素分组为python中的元组?
【发布时间】:2017-09-19 06:57:16
【问题描述】:

我已经读取了 python 列表中目录中所有文件的名称,如下所示:

files = ['ch1.txt', 'ch2.txt', 'ch3_1.txt', 'ch4_2.txt', 'ch3_2.txt', 'ch4_1.txt'] 

我想要做的是将相似的文件分组为列表中的元组。上面的例子应该是这样的

files_grouped = ['ch1.txt', 'ch2.txt', ('ch3_1.txt', 'ch3_2.txt'), ('ch4_1.txt', 'ch4_2.txt')]

我尝试过的一种方法是将需要分组的元素从列表中分离出来

groups = tuple([file for file in files if '_' in file])
single = [file for file in files if not '_' in file]

我会创建一个新列表,将两者都附加。但是如何创建groups 作为ch3ch4 的元组列表,比如[('ch3_1.txt', 'ch3_2.txt'), ('ch4_1.txt', 'ch4_2.txt')] 而不是一个大元组?

【问题讨论】:

    标签: python python-3.x list tuples


    【解决方案1】:

    没有一个答案可以为您提供适用于任何类型文件名的通用解决方案。如果你想解决这个问题,我认为你应该使用正则表达式。

    import itertools
    import re
    
    sorted_files = sorted(files, key=lambda x: re.findall('(\d+)_(\d+)', x))    
    out = [list(g) for _, g in itertools.groupby(sorted_files, 
                           key=lambda x: re.search('\d+', x).group() )]
    
    print(out)
    [['ch1.txt'],
     ['ch2.txt'],
     ['ch3_1.txt', 'ch3_2.txt'],
     ['ch4_1.txt', 'ch4_2.txt']]
    

    请注意,这适用于任何命名格式,而不仅仅是chX_X

    如果您希望输出与描述的确切格式一致,您可以进行一些额外的后期处理:

    out = [o[0] if len(o) == 1 else tuple(o) for o in out]
    print(out)
    ['ch1.txt', 'ch2.txt', ('ch3_1.txt', 'ch3_2.txt'), ('ch4_1.txt', 'ch4_2.txt')]
    

    正则表达式详细信息

    第一个正则表达式按章节和小节排序。

    (       # first group 
    \d+     # 1 or more digits
    )
    _       # literal underscore
    (       # second group
    \d+     # 1 or more digits
    )
    

    第二个正则表达式仅按章节章节分组 - 具有相同章节的所有章节都分组在一起。

    【讨论】:

    • 谢谢,我能够在我的代码中采用这个解决方案,它对我有用。
    【解决方案2】:

    您可以使用字典(或者,为了更简单地初始化 collections.defaultdict

    from collections import defaultdict
    from pprint import pprint
    
    files = ['ch1.txt', 'ch2.txt', 'ch3_1.txt', 'ch4_2.txt', 'ch3_2.txt', 'ch4_1.txt']
    
    grouped = defaultdict(list)  # create an empty list for not existent entries
    
    for f in files:
        key = f[:3]
        grouped[key].append(f)
    
    pprint(grouped)
    

    结果:

    defaultdict(<class 'list'>,
                {'ch1': ['ch1.txt'],
                 'ch2': ['ch2.txt'],
                 'ch3': ['ch3_1.txt', 'ch3_2.txt'],
                 'ch4': ['ch4_2.txt', 'ch4_1.txt']})
    

    如果你想要你的元组列表,你可以这样做:

    grouped = [tuple(l) for l in grouped.values()]
    

    这是

    [('ch1.txt',),
     ('ch2.txt',),
     ('ch3_1.txt', 'ch3_2.txt'),
     ('ch4_2.txt', 'ch4_1.txt')]
    

    【讨论】:

      【解决方案3】:

      也许您可以对文件名列表进行排序,然后使用groupby() 这样做:

      例如

      from itertools import groupby
      
      files = ['ch1.txt', 'ch2.txt', 'ch3_1.txt', 'ch4_2.txt', 'ch3_2.txt', 'ch4_1.txt']
      
      print([tuple(g) for k,g in groupby(sorted(files),key=lambda x : x[:-4].split("_")[0])])
      

      结果:

      [('ch1.txt',), ('ch2.txt',), ('ch3_1.txt', 'ch3_2.txt'), ('ch4_1.txt', 'ch4_2.txt')]
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 1970-01-01
        • 2017-04-26
        • 2021-03-31
        • 2021-11-18
        • 2017-04-11
        • 2016-03-03
        相关资源
        最近更新 更多