1

我正在尝试在两个文件中匹配(什么是网络登录用户名)。All 是我(或将要)有兴趣匹配的名称的文本文件。目前,我正在做这样的事情:

def find_files(directory, pattern):
    #directory= (raw_input("Enter a directory to search for Userlists: ")
    directory=("c:\\TEST")
    os.chdir(directory)
    for root, dirs, files in os.walk(directory):
        for basename in files:
            if fnmatch.fnmatch(basename, pattern):
                filename = os.path.join(root, basename)
                yield filename


for filename in find_files('a-zA-Z0-9', '*.txt'):
    with open (filename, "r") as file1:
       with open ("c:/All.txt", "r") as file2:
            list1 = file1.readlines()[18:]
            list2 = file2.readlines()
            for i in list1:
                for j in list2:
                    if i == j:

我是 python 新手,想知道这是否是最好、最有效的方法。对我来说,即使是新手,似乎也有点笨拙,但以我目前的编码知识是我目前能想到的最好的。任何帮助和建议将不胜感激。

4

1 回答 1

4

您想先将一个文件读入内存,然后将其存储在一组中。集合中的成员资格测试非常有效,为第一个文件中的每一行循环遍历第二个文件的行要高效得多。

然后你只需要读取第二个文件,并逐行处理它并测试行是否匹配。

保存在内存中的文件取决于All.txt. 如果它小于 1000 行左右,只需将其保存在内存中并将其与其他文件进行比较。如果All.txt真的很大,请为每个处理重新打开它file1,并仅将前 18 行读取file1到内存中,并将它们与 中的每一行逐行匹配All.txt

要仅读取文件的 18 行,请使用itertools.islice(); 文件是可迭代的,islice()是选择要读取的行子集的最简单方法。

先读All.txt入内存:

from itertools import islice

with open ("c:/All.txt", "r") as all:
    # storing lines without whitespace to make matching a little more robust
    all_lines = set(line.strip() for line in all)

for filename in find_files('a-zA-Z0-9', '*.txt'):
    with open(filename, "r") as file1:
        for line in islice(file1, 18):
            if line.strip() in all_lines:
                 # matched line

如果All.txt较大,则先将每个文件的这 18 行存储在一个集合中,然后重新打开All.txt并逐行处理:

for filename in find_files('a-zA-Z0-9', '*.txt'):
    with open(filename, "r") as file1:
        file1_lines = set(line.strip() for line in islice(file1, 18))
    with open ("c:/All.txt", "r") as all:
        for line in all:
            if line.strip() in file1_lines:
                 # matched line

请注意,您不必更改; 中的目录find_files()os.walk()已传递目录名称。该fnmatch模块还有一个.filter()方法,使用它来循环files而不是fnmatch.fnmatch()单独使用每个文件:

def find_files(directory, pattern):
    directory = "c:\\TEST"
    for root, dirs, files in os.walk(directory):
        for basename in fnmatch.filter(files, pattern):
            yield os.path.join(root, basename)
于 2013-05-16T09:04:42.653 回答