Как игнорировать знаки препинания при сравнении двух файлов в python

#python

#python

Вопрос:

Я пытаюсь расширить сценарий сравнения на python, чтобы не включать элементы регистра, такие как (имена в нижнем / верхнем регистре и использование кавычек). В настоящее время у меня есть следующее

compare.py

 with open('old.csv', 'r') as t1, open('new.csv', 'r') as t2:
    fileone = t1.readlines()
    filetwo = t2.readlines()

with open('update.csv', 'w') as outFile:
    for line in filetwo:
        if line not in fileone:
            outFile.write(line)
  

Это правильно сравнивает два файла и выводит разницу в третьем файле. Но, скажем, у меня есть следующее

old.csv

 "testCaseA",
"testCaseB",
"testCaseC"
  

new.csv

 testCaseA,
testCaseB,
  

update.csv должен быть

 testCaseC
  

Комментарии:

1. Просто отфильтруйте заглавные буквы и знаки препинания. Вы можете использовать str.lower для фильтрации заглавных букв и что-то вроде понимания списка для фильтрации знаков препинания.

Ответ №1:

Использование split() и strip() для удаления 'n' , , и double " из элементов в списке, а затем понимание списка, чтобы найти разницу:

 with open('old.txt', 'r') as t1, open('new.txt', 'r') as t2:
     fileone = [i.split(',n', 1)[0].strip('"') for i in t1.readlines()]
     filetwo = [i.split(',n', 1)[0].strip(',') for i in t2.readlines()]

# print(fileone)   # ['testCaseA', 'testCaseB', 'testCaseC']
# print(filetwo)   # ['testCaseA', 'testCaseB']

s = set(filetwo)
print([x for x in fileone if x not in s])
  

ВЫВОД:

 ['testCaseC']
  

Комментарии:

1. Спасибо за подробный ответ. Предназначено ли это также для работы » в самих именах? Например, удаление тестового примера «в 1/2» a

Ответ №2:

Комментарии:

1. вы можете улучшить свой ответ, показав короткий пример, а затем просто сославшись на один 🙂

Ответ №3:

Я думаю, что следующий код более симпатичен:

 from pathlib import Path

fn1, fn2 = 'old.csv', 'new.csv'
ss1, ss2 = [Path(fn).read_text().splitlines() for fn in (fn1, fn2)]
for ss in (ss1, ss2):
    for i, v in enumerate(ss):
        ss[i] = v.strip(''",')

set1, set2 = [set(ss) for ss in (ss1, ss2)]

for i, line in enumerate(ss1, 1):
    if line not in set2:
        print(f'line {i}: `{line}` : in {fn1}, but not in {fn2}')

for i, line in enumerate(ss2, 1):
    if line not in set1:
        print(f'line {i}: `{line}` : in {fn2}, but not in {fn1}')
  

Последние два цикла for также могут быть:

 for ss, line_set, f1, f2 in ((ss1, set2, fn1, fn2), (ss2, set1, fn2, fn1)):
    for i, line in enumerate(ss, 1):
        if line not in line_set:
            print(f'line {i}: `{line}` : in {f1}, but not in {f2}')
  

Комментарии:

1. Спасибо за подробный ответ. Предназначено ли это также для работы » в самих именах? Например, удаление тестового примера «в 1/2» a