Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как удалить одинаковые слова в двух файлах?

Автор вопроса: Santosh KumarОтветов: 6

У меня есть два текстовых файла.

file1.txt содержит:

gedit
google chrome
git
vim
foo
bar

file2.txt содержит:

firefox
svn
foo
vim

Как написать скрипт, который при выполнении (с аргументами file1.txt и file2.txt) проверяет дублирование текста в каждой строке (Я имею в виду, что он должен обрабатываться построчно), удаляет дублированный текст в обоих файлах.

Таким образом, после обработки файлы file1.txt и file2.txt должны иметь следующее содержимое:

gedit
google chrome
git
bar
firefox
svn

Обратите внимание, что foo и vim удалены из обоих файлов.

Любое руководство?

  • зачем 2 файла с одинаковым содержимым? насколько велики эти файлы, могут ли они поместиться в память, когда оба открыты одновременно? + что вы уже пробовали? Aprillion 23.06.2012
  • Попробуйте использовать структуру данных set() для поиска дубликатов. docs.python.org/library/sets.html user590028 23.06.2012
  • @deathApril Предположим, я переустанавливаю Ubuntu. Итак, я получаю список пакетов с помощью команды dpkg --get-selection (file1.txt), и есть еще один список, сделанный мной самостоятельно (file2.txt), этот файл содержит то, что я помню, что я установил. После переустановки Ubuntu я установил программное обеспечение, увидев file2.txt. Теперь необходимо установить оставшееся содержимое обоих файлов. Теперь остальная часть в моем вопросе.... Santosh Kumar 23.06.2012
  • Всегда старайтесь думать о правильном типе данных для каждой отдельной задачи. Если это удастся, ваш путь сгладится. Самый простой способ - искать уже существующие типы данных, которые могут соответствовать вашим потребностям (и потребностям внутренних функций): меньше проблем, больше эффективности. Paul 23.06.2012
  • порядок контента имеет значение? Ashwini Chaudhary 23.06.2012
  • @Santosh, тогда ознакомьтесь с моим решением. Ashwini Chaudhary 23.06.2012

python

Ответы

Ответ 1 · рейтинг 3 · Ashwini Chaudhary

with open('file1.txt','r+') as f1 ,open('file2.txt','r+') as f2:
    file1=set(x.strip() for x in f1 if x.strip())
    file2=set(x.strip() for x in f2 if x.strip())
    newfile=file1.symmetric_difference(file2) #symmetric difference removes those values which are present in both sets, and returns a new set.
    f2.truncate(0) #truncate the file to 0 bytes
    f1.truncate(0)
    f2.seek(0) # to push the cursor back to the starting pointing in the file.
    f1.seek(0)
    for x in newfile:
        f1.write(x+'\n')
        f2.write(x+'\n')

теперь оба файла содержат:

svn
git
firefox
gedit
google chrome
bar

Ответ 2 · doniyor

Вы сохраните отфильтрованный файл как третий файл?

В любом случае, сделайте 2 цикла для каждого файла и сравните каждое значение индекса цикла с другим, и если они равны, удалите и переместите с уважением. Псевдокод:

Def func(File a, File b):
 for i in a:
    for j in b:
      if a[i]==b[j]:
        copy and move
      endif
     endfor
  endfor

Ответ 3 · lucemia

если я правильно понимаю ваш вопрос, это должно быть легко.

alist = []
for i in ifile1:
    alist.append(i)

for i in ifile2:
    if i in alist:
        alist.remove(i)
    else:
        alist.append(i)

for i in alist:
    print i

Ответ 4 · Aprillion

если файлы достаточно малы, чтобы поместиться в память, это сделает работу:

with open("file1.txt", "r") as f1, open("file2.txt", "r") as f2:
    # create a set from the bigger file
    result = set(x.strip() for x in f1.readlines())
    # remove duplicates or add unique values from 2nd file
    for line in f2:
        line = line.strip()
        if line in result:
            result.remove(line)
        else:
            result.add(line)
result = "\n".join(result)

# for debug, don't replace original files
with open("file1_out.txt", "w") as f1, open("file2_out.txt", "w") as f2:
    f1.write(result)
    f2.write(result)

# if not inside a function, free memory explicitly
del result

Ответ 5 · Burhan Khalid

Для Python 2.7+, где был представлен Counter

>>> from collections import Counter
>>> file_1 = ['gedit','google chrome','git','vim','foo','bar']
>>> file_2 = ['firefox','svn','foo','vim']
>>> de_dup = [i for i,c in Counter(file_1+file_2).itertimes() if c == 1]
>>> de_dup
['svn', 'git', 'bar', 'gedit', 'google chrome', 'firefox']

Ответ 6 · рейтинг -1 · Kos

Начнем с имен входных файлов:

files = ('raz.txt','dwa.txt')

И некоторые вспомогательные функции. Это генератор, который читает все слова из файла,

def read(filename):
    with open(filename) as f:
        for line in f:
            if len(line)>0:
                yield line.strip()

И это записывает последовательность в файл.

def write(filename, lines):
    with open(filename, 'w') as f:
        f.write('\n'.join(lines))

Итак, давайте создадим два генератора - по одному для каждого входного файла.

words = [read(filename) for filename in files]

Затем давайте преобразуем этот список генераторов в список наборов

wordSets = map(set, words)

Теперь у нас есть список из двух наборов, содержащих только уникальные слова из каждого файла.

Давайте создадим еще один набор, содержащий слова, присутствующие во всех входных файлах, путем пересечения их наборов:

commonWords = set.intersection(*wordSets)

И время для перезаписи.

for filename in files:

Так как мы хотим сохранить в точно такой же файл, то, к сожалению, нам нужно сначала прочитать все его содержимое в память, а потом уже оттуда писать. (Если вам нужен вывод в разных файлах, вам не нужно буферизовать файл.

Давайте создадим генератор считывателей, а затем прочитаем все это в память, обернув его list():

    lines = list(read(filename))

а затем записать слова обратно в данный файл по порядку, но только если они не в commonWords

    write(filename, (word for word in lines if word not in commonWords))

Вход:

раз.txt

gedit
google chrome
git
vim
foo
bar

два.txt

firefox
svn
foo
vim

Выход:

раз.txt

gedit
google chrome
git
bar

два.txt

firefox
svn

Дубликаты были удалены из обоих.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы