Как получить разницу между двумя списками на основе подстрок, в которых каждая строка находится в отдельных списках - PullRequest
1 голос
/ 05 января 2010

У меня два длинных списка, один из файла журнала, который содержит строки, отформатированные как

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

и второй файл в формате csv. Мне нужно создать список всех записей в file2, которые не содержат адрес электронной почты в файле журнала, при сохранении формата 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

А затем сравните с файлом file2:

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 ]

1 голос
/ 05 января 2010

Вы можете создать набор писем, а затем:

# 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 включает редактирование на месте.

И используйте набор для электронных писем вместо списка, как сказал Аарон, не только из-за скорости, но и для устранения дубликатов.

1 голос
/ 05 января 2010

line.split() разделяется на пустое пространство. Вместо этого используйте line.split(',').

Также: имеет ли значение порядок строк? Если нет, то вам следует использовать set() вместо списка. Это сделает код намного быстрее.

0 голосов
/ 06 января 2010

вот еще один способ, с минималистической проверкой позиции адресата электронной почты.

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
...