如何基于多个列表中字符串的子串来获取两个列表的差异

1 投票
3 回答
598 浏览
提问于 2025-04-15 17:40

我有两个很长的列表,一个是从日志文件中提取的,里面的内容格式像这样:

201001050843 blah blah blah <email@site.com> blah blah

另一个是csv格式的文件。我需要生成一个列表,里面包含文件2中所有不包含日志文件中邮箱地址的条目,同时保持csv格式。

举个例子
日志文件的内容是:

201001050843 blah blah blah <email@site.com> blah blah
201001050843 blah blah blah <email2@site.com> blah blah

文件2的内容是:

156456,bob,sagget,email@site.com,4564456
156464,bob,otherguy,email@anothersite.com,45644562

输出结果应该是:

156464,bob,otherguy,email@anothersite.com,45644562

现在我从日志中提取邮箱,并把它们放到另一个列表中,使用的是:

sent_emails =[]
for line in sent:
    try:
        temp1= line.index('<')
        temp2 = line.index('>')
        sent_emails.append(line[temp1+1:temp2])
    except ValueError:
        pass

然后我用以下方法来和文件2进行比较:

lista = mail_lista.readlines()
for line in lista:
    temp = line.split()
    for thing in temp:
        try:
            if thing.index('@'):
                if thing in sent_emails:
                    lista.remove(temp)
        except ValueError:
            pass
newa.writelines(lista)

或者:

for line in mail_listb:
    temp = line.split()
    for thing in temp:
        try:
            if thing.index('@'):
                if thing not in sent_emails:
                    newb.write(line)
        except ValueError:
            pass

但是这两种方法都返回了文件2中的所有内容!

谢谢你们的帮助。

编辑:感谢你们推荐使用集合,这让我感到速度提升比我想象的要大。哈希表真不错!从现在开始我肯定会更频繁地使用集合。

3 个回答

0

这里有另一种方法,它对电子邮件地址的位置进行了简单的检查。

import fileinput
emails=[]
for line in open("file1"):
    start=line.find("<")
    end=line.find(">")
    if start != -1 and end !=-1:
        emails.append(line[start+1:end])

for line in fileinput.FileInput("file2",inplace=1):
    p = line.split(",")
    for item in p:
        if "@" in item and item not in emails:
            print line.strip()

输出结果

$ ./python.py
156464,bob,otherguy,email@anothersite.com,45644562
1

line.split() 是用来把一行文字按照空格分开的。如果你想用逗号来分开,可以用 line.split(',')

另外:行的顺序重要吗?如果不重要,那你其实可以用 set() 来代替列表,这样代码会运行得更快。

1

你可以像你之前那样创建一组电子邮件,然后:

# emails is a set of emails
for line in fileinput.input("csvfile.csv",inplace =1):
    parts = line.split(',')
    if parts[3] not in emails:
        print line

这个方法只有在CSV文件中的电子邮件总是位于第4个位置时才有效。

fileinput 允许你直接在文件中进行编辑。

而且,正如Aaron所说,使用集合来存储电子邮件,而不是列表,这样不仅速度更快,还能避免重复的邮件。

撰写回答