【问题标题】:Find files with same initial part of the name in two folders在两个文件夹中查找名称首字母相同的文件
【发布时间】:2018-04-09 12:34:56
【问题描述】:

我使用listdir读取了两个文件夹中的文件:

from os import listdir 
list_1 = [file for file in listdir("./folder1/") if file.endswith(".csv")]
list_2 = [file for file in listdir("./folder2/") if file.endswith(".json")]

现在我有两个列表:

list_1 = ['12_a1_pp.csv', '32_a3_pp.csv', '45_a17_pp.csv', '81_a123_pp.csv']
list_2 = ['12_a1.json', '32_a3.json', '61_a54.json']

我想找到相应的两个子列表,其中包含名称的初始部分相同的那些文件。换句话说:

list_1b = ['12_a1_pp.csv', '32_a3_pp.csv']
list_2b = ['12_a1.json', '32_a3.json']

我该怎么做?

PS 请注意,listdir 部分对于回答问题可能无关紧要。我只包括它,因为如果listdir 的结果保证按字母顺序排列,那么这可能有助于遍历这两个列表。当然,在这个简单的示例中,列表很短,但在实际用例中,它们包含数百个文件。

【问题讨论】:

  • 我个人会考虑在这里使用类似 glob 模式匹配的东西:docs.python.org/2/library/glob.html
  • 为什么不直接从列表 1 中删除特殊子字符串“_pp.scv”和从列表 2 中删除“.json”,并使用两个嵌套循环进行相等性测试?

标签: python list set-intersection


【解决方案1】:

更 Pythonic 的方法是使用 &(交集)运算符来表示集合:

common = set(x[:-7] for x in list_1) & set(x[:5] for x in list_2)
list_1b = [x + '_pp.csv' for x in common]
list_2b = [x + '.json' for x in common]

编辑:如果您需要为每个列表拆分特定字符(请参阅注释),这里是一个更新版本(在 list_1 中搜索最后一个“_”并在 list_2 中搜索最后一个“.”):

common = set(x[:x.rindex('_')] for x in list_1) & set(x[:x.rindex('.')] for x in list_2)

【讨论】:

  • 这很好,但我不喜欢它依赖于计算字符数的事实。 split 或类似的方法会更干净。
  • @DeltaIV:你是对的,通用解决方案比特定解决方案更好。但是您的 OP 没有向我们提供有关您可能遇到的文件名变化的任何信息。甚至拆分方法也未定义:我们应该在最后一个下划线上拆分吗?在倒数第二个下划线?或者是其他东西 ?只要您不提供有关数据的详细信息,人们就只能提供适用于您的示例的解决方案...
  • @DeltaIV:最后一句话,你说性能对你的应用程序很重要,所以支持 jpp 提出的字典方法是不合逻辑的,它的速度几乎是基于方法的两倍纯集合(我获得了 7.59 秒和 4.08 秒的 1000 万执行官)。
  • 关于时间:如何在 Python 中进行基准测试?有参考吗?在R中有一个非常不错的包microbenchmark,我不知道Python中有一个对应的模块。
  • 最简单的解决方案是使用 IPython 及其神奇的命令 %timeit。请参阅this link 了解更多信息
【解决方案2】:

这是使用字典推导和set.intersection 的一种方式。

list_1 = ['12_a1_pp.csv', '32_a3_pp.csv', '45_a17_pp.csv', '81_a123_pp.csv']
list_2 = ['12_a1.json', '32_a3.json', '61_a54.json']

start_1 = {k: '_'.join(k.split('_')[:-1]) for k in list_1}
start_2 = {k: k.split('.')[0] for k in list_2}

start_intersect = set(start_1.values()) & set(start_2.values())

list_1b = [k for k, v in start_1.items() if v in start_intersect]
list_2b = [k for k, v in start_2.items() if v in start_intersect]

如果任何“XY”的文件名以“_XY.csv”结尾,此方法同样有效。它依赖于文件名的格式而不是单个字母。

【讨论】:

  • 性能确实很重要。你能展示如何消除重复分裂吗?
  • '_'.join(string_list) 表示使用分隔符'_' 加入字符串列表string_list 的元素,对吗?
  • @DeltaIV,请参阅更新。而你对str.join的理解是正确的。
  • 太棒了!如果可以的话+2 :-) 但最后两行不应该是list_1b = [k for k, v in list_1.items() if v in start_intersect]list_2b = [k for k, v in list_2.items() if v in start_intersect] 吗?
  • @DeltaIV,不,没必要。字典已经包含您列表中的所有项目。此外,列表没有 items 方法。
【解决方案3】:
list_1 = ['12_a1_pp.csv', '32_a3_pp.csv', '45_a17_pp.csv', '81_a123_pp.csv']
list_2 = ['12_a1.json', '32_a3.json', '61_a54.json']

list_1_C = [i.split(".")[0].replace("_pp", "") for i in list_1]     #Check List
list_2_C = [i.split(".")[0] for i in list_2]                        #Check List

print([list_1[i] for i, v in enumerate(list_1_C) if v in list_2_C])
print([list_2[i] for i, v in enumerate(list_2_C) if v in list_1_C])

输出:

['12_a1_pp.csv', '32_a3_pp.csv']
['12_a1.json', '32_a3.json']

【讨论】:

    【解决方案4】:

    仔细想想,这很简单,所以这里是:

    list_1 = ['12_a1_pp.csv', '32_a3_pp.csv', '45_a17_pp.csv', '81_a123_pp.csv']
    list_2 = ['12_a1.json', '32_a3.json', '61_a54.json']
    starters = [eachfile.partition(".")[0] for eachfile in list2]
     for eachelement in starters:
        for eachfile in list_1:
           if eachfile.startswith(eachelement):
              list_1b.append(eachfile)
              list_2b.append(eachelement+".json")
    

    此外,如果您想针对这种情况:

    collective_set_1 = { each.replace("_pp.csv","") for each in list_1}
    collective_set_2 = { each.replace(".json","") for each in list_2}
    intersection = collective_set_1.intersection(collective_set2)
    list_1b = [ each+"_pp.csv" for each in intersection ]
    list_2b = [ each+".json" for each in intersection ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-11
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多