【问题标题】:How to properly use a list comprehension in Python?如何在 Python 中正确使用列表推导?
【发布时间】:2021-11-20 06:40:12
【问题描述】:

我有两个目录。它们都包含 TXT 文件。对于dir_1 中的每个TXT 文件,我正在尝试在dir_2 中获取匹配的TXT 文件。如果dir_1 的日期(在文件名中)与dir_2 中的文件日期匹配,则匹配。

dir_1 = c:\data\desktop\pointA\txt-files
dir_2 = c:\data\desktop\pointB\txt-files

dir_1 包含这样的文件(这些目录可以包含多个相同日期但不同时间的文件):

AAA_C1_20200907-07u43m55s_ab.txt
AAA_T8_20200907-08u18m55s_ab.txt
FFF_T8_20201025-12u58m55s_ab.txt
FFF_T8_20201025-05u53m55s_ab.txt

dir_2 包含这样的文件(这些文件具有唯一的日期):

MM2020-09-07-AB.dat
MM2020-10-25-AB.dat
MM2020-10-26-AB.dat

这是我的代码:

dir_1 = os.listdir(dir_1)
dir_2 = os.listdir(dir_2)

dir_2_dates = []
for file in dir_2:
    find = re.search("MM(.+?)AB", file).group(1)
    dir_2_dates.append(find)

for dir_1_file in dir_1:
    dir_1_date = re.search("_(.\d+)-", dir_1_date ).group(1)
    if dir_1_date in dir_2_dates:
            
            matching_dir_2 = [file for file in dir_2 if file == dir_1_date ]
            print(matching_dir_2)

期望的输出:

MM20200907AB.dat
MM20200907AB.dat
MM20201025AB.dat
MM20201025AB.dat

我当前的输出是空的

【问题讨论】:

  • 作为调试的第一步,您是否尝试过打印您提取的日期的样子?
  • 似乎您正在将20200907 之类的字符串与2020-09-07- 之类的字符串进行比较。 Python 不知道那些应该是日期,并且它们应该是相等的。您必须对它们进行规范化,以便它们实际上 相等。
  • 你们能告诉我你的意思吗?

标签: python list for-loop list-comprehension


【解决方案1】:

有几个问题。您的第一个数据匹配会留下斜杠。所以这消除了这一点。接下来,您将匹配斜线到不匹配,所以这会去除那些。最后,我不知道为什么在最后一个 for 循环中有一个理解。这是一个有效的实现,但我不确定它是否是您所追求的,因为您想要的输出列出了 4 个文件,这些文件甚至都不存在于任何一个列表中。

import re

DIR1 = [
    "AAA_C1_20200907-07u43m55s_ab.txt",
    "AAA_T8_20200907-08u18m55s_ab.txt",
    "FFF_T8_20201025-12u58m55s_ab.txt",
    "FFF_T8_20201025-05u53m55s_ab.txt",
]

DIR2 = [
    "MM2020-09-07-AB.dat",
    "MM2020-10-25-AB.dat",
    "MM2020-10-26-AB.dat",
]

dir_2_dates = []
for file in DIR2:
    find = re.search("MM(.+?)-AB", file).group(1).replace("-", "")
    dir_2_dates.append(find)

print([x for x in DIR1 if re.search("_(.\d+)-", x).group(1) in dir_2_dates])

输出:

[
    'AAA_C1_20200907-07u43m55s_ab.txt',
    'AAA_T8_20200907-08u18m55s_ab.txt',
    'FFF_T8_20201025-12u58m55s_ab.txt',
    'FFF_T8_20201025-05u53m55s_ab.txt'
]

【讨论】:

    【解决方案2】:

    我建议首先将 dir_2 中的文件名分组到字典中,使用日期作为键。这样,您不必为来自dir_1 的每个文件再次搜索整个dir_2。 然后,您可以在该字典中查找来自dir_2 的文件,以查找来自dir_1 的文件中的任何日期。不过,请确保将日期标准化,使其具有相同的格式,即从 dir_2 中的日期中删除 -

    import re, collections
    
    by_date = collections.defaultdict(list)
    for f in dir_2:
        d = re.search("MM(.+?)-AB", f).group(1).replace("-", "")
        by_date[d].append(f)
    
    for f in dir_1:
        d = re.search("_(.\d+)-", f).group(1)
        if d in by_date:
            print(f, "->", by_date[d])
    

    这不使用列表推导,但应该快得多。

    【讨论】:

    • 这很好,介意我在聊天中问你一些额外的事情吗?它与目录chat.stackoverflow.com/rooms/237147/…有关
    • @ManCity10 没有看到你的评论;这是什么,你不能把它作为另一个评论发在这里吗?
    • 嗯,它需要很多解释,不能在评论中这样做.. 在if d in by_date 之后我想打开 dir_2 中与 dir_1 中的当前文件匹配的 txt 文件。所以我想根据一些需求从dir_2中的文件中加载一些数据并将其写回by_data [d]。但实际上我需要为 by_data 中的每个键都这样做
    • @ManCity10 最好将此作为单独的后续问题发布(您可以链接到此问题以获取上下文),解释“一些数据”和“一些要求”究竟是什么,以及如何将这些写回字典(这甚至不是您原始设置的一部分)。
    【解决方案3】:

    你在做

    [file for file in dir_2 if file == dir_1_date ]
    

    其中file是dir2中的文件名,即:

    MM2020-09-07-AB.dat
    MM2020-10-25-AB.dat
    MM2020-10-26-AB.dat
    

    并将 (==) 与 dir_1_date 进行比较

    dir_1_date = re.search("_(.\d+)-", dir_1_date ).group(1)
    

    因此dir_1_date 是后跟一个或多个数字的任何字符。因为文件名由字母、数字、-. 组成,所以不可能相等。

    【讨论】:

    • 那么我应该怎么做才能得到我想要的输出呢?
    猜你喜欢
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多