【问题标题】:Python search a file for text using input from another filePython使用来自另一个文件的输入搜索文件中的文本
【发布时间】:2013-11-12 15:54:54
【问题描述】:

我是 python 和编程的新手。我需要一些关于 python 脚本的帮助。有两个文件,每个文件都包含电子邮件地址(超过 5000 行)。输入文件包含我想在数据文件中搜索的电子邮件地址(也包含电子邮件地址)。然后我想将输出打印到文件或显示在控制台上。我搜索脚本并能够修改,但我没有得到想要的结果。你能帮帮我吗?

dfile1 (50K lines)
yyy@aaa.com
xxx@aaa.com
zzz@aaa.com


ifile1 (10K lines)
ccc@aaa.com
vvv@aaa.com
xxx@aaa.com
zzz@aaa.com

Output file
xxx@aaa.com
zzz@aaa.com



datafile = 'C:\\Python27\\scripts\\dfile1.txt'
inputfile = 'C:\\Python27\\scripts\\ifile1.txt'

with open(inputfile, 'r') as f:
names = f.readlines()

outputlist = []

with open(datafile, 'r') as fd:
  for line in fd:
    name = fd.readline()
    if name[1:-1] in names:
        outputlist.append(line)
    else:
        print "Nothing found"
 print outputlist

新代码

with open(inputfile, 'r') as f:
    names = f.readlines()
outputlist = []

with open(datafile, 'r') as f:
    for line in f:
        name = f.readlines()
        if name in names:
            outputlist.append(line)
        else:
            print "Nothing found"
    print outputlist

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:

    也许我遗漏了一些东西,但为什么不使用一对呢?

    #!/usr/local/cpython-3.3/bin/python
    
    data_filename = 'dfile1.txt'
    input_filename = 'ifile1.txt'
    
    with open(input_filename, 'r') as input_file:
        input_addresses = set(email_address.rstrip() for email_address in input_file.readlines())
    
    with open(data_filename, 'r') as data_file:
        data_addresses = set(email_address.rstrip() for email_address in data_file.readlines())
    
    print(input_addresses.intersection(data_addresses))
    

    【讨论】:

    • (... for email_address in data_file) 就足够了。文件是 Python 中行的迭代器。无需致电.readlines()
    【解决方案2】:

    mitan8 给出了你遇到的问题,但我会这样做:

    with open(inputfile, "r") as f:
        names = set(i.strip() for i in f)
    
    output = []
    
    with open(datafile, "r") as f:
        for name in f:
            if name.strip() in names:
                print name
    

    这样可以避免将较大的数据文件读入内存。

    如果您想写入输出文件,您可以在第二个with 语句中执行此操作:

    with open(datafile, "r") as i, open(outputfile, "w") as o:
        for name in i:
            if name.strip() in names:
                o.write(name)
    

    【讨论】:

    • 对于this reason末尾没有换行符的文件可能会失败
    • 文件是 Python 中行的迭代器。无需调用 .readlines()
    • if name in names: o.write(name) -> if name.strip() in names: o.writeline(name)。您可以在一个 with-statement 中打开多个文件(只需添加逗号)。
    • @J.F.Sebastian 已编辑!我之所以有readlines是因为我在添加生成器表达式调用strip之后没有删除它。
    【解决方案3】:

    我会这样做:

    names=[]
    outputList=[]
    with open(inputfile) as f:
        for line in f:
            names.append(line.rstrip("\n")
    
    myEmails=set(names)
    
    with open(outputfile) as fd, open("emails.txt", "w") as output:
        for line in fd:
            for name in names:
                c=line.rstrip("\n")
                if name in myEmails:
                    print name #for console
                    output.write(name) #for writing to file
    

    【讨论】:

    • 对于结尾没有换行符的文件可能会失败;你可以打电话给.rstrip("\n") 来修复它。此处列表也无效,您可以像其他答案一样使用set()
    【解决方案4】:

    我认为您的问题源于以下几点:

    name = fd.readline()
    if name[1:-1] in names:
    

    name[1:-1] 对每个电子邮件地址进行切片,以便您跳过第一个和最后一个字符。虽然在“dfile”中加载名称数据库时,通常跳过最后一个字符(换行符'\n')可能会很好

    with open(inputfile, 'r') as f:
        names = f.readlines()
    

    您正在包括换行符。所以,根本不要对“ifile”中的名称进行切片,即

    if name in names:
    

    【讨论】:

    • 我将其更改为 if name in names。但它给了我这个错误。文件“C:\Python27\scripts\test.py”,第 12 行,在 中 name = f.readlines() ValueError:混合迭代和读取方法会丢失数据
    • 你能确保你的代码中的缩进是正确的吗?这将帮助我理解你的错误。
    • 这是我的代码:with open(inputfile, 'r') as f: names = f.readlines() # print names outputlist = [] with open(datafile, 'r') as f : for line in f: name = f.readlines() if name in names: outputlist.append(line) else: print "Nothing found" print outputlist
    • @HarryD 你能编辑问题以获得该代码吗?
    • @HarryD:您的“新代码”中有错字,导致您出现错误。应该是name = f.readline()(不是readlines())。
    【解决方案5】:

    我认为您可以删除 name = fd.readline(),因为您已经在 for 循环中找到了该行。除了每次读取一行的 for 循环之外,它还会读取 another 行。另外,我认为name[1:-1] 应该是name,因为您不想在搜索时去掉第一个和最后一个字符。 with 自动关闭打开的文件。

    PS:我会怎么做:

    with open("dfile1") as dfile, open("ifile") as ifile:
        lines = "\n".join(set(dfile.read().splitlines()) & set(ifile.read().splitlines())
    print(lines)
    with open("ofile", "w") as ofile:
        ofile.write(lines)
    

    在上述解决方案中,基本上我将两个文件的行的并集(两个集合的元素部分)来查找公共行。

    【讨论】:

    • 可爱的解决方案,但是如果输入是 ~10k 行,使用 readlines() 是否合适?老实说,我对这种内存使用规模没有太多经验。
    • @kevinsa5 每行大约需要60个字节(Python的字符串类型有相当多的开销),那么集合应该是大约600k+开销(无论如何都小于1兆字节)。
    • 我不熟悉使用集合,但这会得到他在输入文件中寻找的电子邮件地址吗?还是这能得到一切?
    • @BraydonKains 我的回答只是找到了共同点,这和他的问题是一样的,或者我认为是这样。
    • .readlines() 在字符串中留下一个换行符;你可以改用file.read().splitlines()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 2013-12-06
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多