如何从两个文件夹中读取文件并避免在 Python 中重复

Posted

技术标签:

【中文标题】如何从两个文件夹中读取文件并避免在 Python 中重复【英文标题】:How to read files from two folders and avoid duplicates in Python 【发布时间】:2018-11-09 21:48:32 【问题描述】:

我有以下文件夹,我从中读取 SQL 文件并将它们保存为变量:

++folder1
  -1.sql
  -2.sql
  -3.sql
++folder2
  -2.sql

以下代码可以很好地处理单个文件夹。我如何修改此代码以不仅从一个文件夹中读取,而且从两个文件夹中读取,如果文件存在于文件夹 2 中,则不要从文件夹 1 中读取同名文件?

folder1 = '../folder1/'
for filename in os.listdir(folder1):
    path = os.path.join(folder1, filename)
    if os.path.isdir(path):
        continue
    with open(folder1 + filename, 'r') as myfile:
        data = myfile.read()
    query_name = filename.replace(".sql", "")
    exec (query_name + " = data")

【问题讨论】:

附带说明,像这样动态创建一堆变量几乎总是一个非常糟糕的主意,使用exec 而不是globalssetattr 是一个更糟糕的主意.将所有内容存储在例如字典中通常会更好。 另外,请注意您正在使用path = os.path.join(folder1, filename),然后在几行之后使用folder1 + filename 而不是仅仅使用path 【参考方案1】:

您可以尝试以下方法:

folders = ['../folder2/','../folder1/']
checked =[]
for folder in folders:
    for filename in os.listdir(folder):
        if filename not in checked:
            checked.append(filename)
            path = os.path.join(folder, filename)
            if os.path.isdir(path):
                continue
            with open(folder + filename, 'r') as myfile:
                data = myfile.read()
            query_name = filename.replace(".sql", "")
            exec (query_name + " = data")

【讨论】:

首先,这与 OP 的要求相反。其次,当它的唯一用途是检查成员资格时,为什么要使用列表而不是集合? 你的意思是相反的?无论是列表还是设置都没有关系,它仅用于检查重复的文件名。 “如果文件夹 2 中存在文件,则不要从文件夹 1 中读取同名文件的规则”。您的代码将读取文件夹 1 中的文件,然后跳过文件夹 2 中的文件。 是的,这就是 OP 的要求。他想避免重复文件。 OP 要求不要从文件夹 1 中读取同名文件,只读取文件夹 2 中的文件。您的代码读取文件夹 1 中的文件,但不读取文件夹 2 中的文件.这不是一回事,恰恰相反。【参考方案2】:

这个问题的答案很简单:调用两次listdir,然后跳过文件夹 1 中同时位于文件夹 2 中的文件。

一种方法是使用集合操作:集合差异a - b 表示a 中不在b 中的所有元素,这正是您想要的。

files1 = set(os.listdir(folder1))
files2 = set(os.listdir(folder2))
files1 -= files2

paths1 = [os.path.join(folder1, file) for file in files1]
paths2 = [os.path.join(folder2, file) for file in files2]
for path in paths1 + paths2:
    if os.path.isdir(path):
        # etc.

附带说明一下,像这样动态创建一堆变量几乎总是一个非常糟糕的主意,使用exec 而不是globalssetattr 是一个更糟糕的主意。将所有内容存储在例如字典中通常会更好。例如:

queries = 
for path in paths1 + paths2:
    if os.path.isdir(path):
        continue
    name = os.path.splitext(os.path.basename(path))[0]
    with open(path) as f:
        queries[name] = f.read()

【讨论】:

如果我保持初始方法并使用您建议的代码的第一部分,我不需要更改初始代码的第 6 行吗? with open(folder1 + filename, 'r') as myfile: @sprogisd 更简单地说,就是open(path)。正如我对您的问题所评论的那样,您已经使用 os.join 创建了该路径,那么为什么不直接使用该路径而不是以不同的方式重新创建相同的字符串呢? 那么with open(path, 'r') as myfile:? 我假设我应该在第 8 行之前添加这行代码:'filename = path.split("/")[-1].并将os.join 替换为os.path.join。我说的对吗? @sprogissd 我修复了os.path.join(感谢您的关注)。但与此同时,您可能应该使用os.path.split(path) 而不是path.split('/'),但是,是的,这会起作用。或者,如果您愿意,您可以在列表中存储一对(路径,文件)值,而不仅仅是路径。

以上是关于如何从两个文件夹中读取文件并避免在 Python 中重复的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中读取文本文件并从中创建两个列表

python 更新文本文件内容

Python:如何从压缩的 json .gz 文件中读取并写入 json 文件

python 读取文档 并创建任意多的list

Python如何从文件读取数据

如何避免两个不同的线程从DB中读取相同的行(Hibernate和Oracle 10g)