1

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

def createMapFile(old_data, new_data, file):
    try:
        if len(old_data) != len(new_data):
            print 'Наборы параметров не соответствуют друг-другу'
        else:
            file = open(file, 'r')  # Opens the file in read-mode
            text = file.read()  # Reads the file and assigns the value to a variable
            file.close()  # Closes the file (read session)
            file = open(mapfile, 'w')
            i = 0
            f = [file.write(text.replace(old_data[i], new_data[i])) for i in range(1, old_data)]
            # file.write(text.replace(old_data[i], new_data[i])) #replaces all instances of our keyword
            return file.close()  # Closes the file (write session)
    except:
        print 'Ошибка:'

Сейчас происходит ошибка, хотя если взять не список и убрать цикл for, заменив его закомментированной строкой, то тогда всё работает, но с одним словом, нужно со списком слов.

jfs
  • 52,361
Rumato
  • 1,678
  • В питоне есть такая структура, как словарь (dictionary). Занести mapfile в словарь, читать file, разбивая на слова и заменять имеющиеся в словаре слова (ключи) на значения (новые слова) – alexlz Sep 28 '13 at 07:30
  • ну вы бы хоть трейс ошибки, что-ли, скопировали бы сюда.

    и вообще не совсем понятно, почему вы используете генератор списка вместо обычного цикла, может поясните?

    – actionless Sep 28 '13 at 12:04

2 Answers2

3

Никогда не используйте try/except без указания конкретного класса исключений. Это приведет к тому, что буду отлавливаться абсолютно все исключения, даже KeyboardInterrupt. Никогда не используйте переменные-счетчики, для этого есть более изящные методы. Не пользуйтесь генераторами списков, так как пользуетесь в этом коде, лучше используйте map(). Используйте итераторы в циклах. Пользуйтесь конструкцией with/as она упрощает код.

def createMapFile(old_data, new_data, file_name, map_file):
    with open(file_name) as file:
        text = file.read()
        for index, replaced_data in enumerate(old_data):
            text = text.replace(replaced_data, new_data[index])
        with open(map_file, 'w') as file:
            file.write(text)
Ukeo
  • 957
  • Спасибо за развёрнутый ответ, учту замечания, с Python-ом пока только поверхностно знаком поэтому с такими ляпами программа, Спасибо! – Rumato Sep 28 '13 at 14:00
  • 1
    @Ukeo, я вот тоже питоном только начал потихоньку баловаться. А вот так:
    def createMapFile(old_data, new_data, file_name, map_file):
       text = open(file_name).read()
       for index, replaced_data in enumerate(old_data):
            text = text.replace(replaced_data, new_data[index]) # это я просто оставил
       open(map_file, 'w').write(text)
    
    
    

    не проще для восприятия? Или в таком коде есть какие-то подводные камни, которых я просто пока не вижу?

    Т.е. какой глубокий смысл в исползовании with?

    – avp Sep 28 '13 at 14:23
  • 1
    @avp Метод with пользуется методами enter() и exit() вызываемого объекта, в данном случае объекта файла, он гарантирует, что независимо от того, будет ли в следующем после него коде исключение или нет, подготовительный и завершающий код enter() и exit() будут выполнены, в данном случае файл обязательно будет закрыт. – Ukeo Sep 29 '13 at 07:35
  • 2
    reduce(lambda x, y: x.replace(*y), zip(old_data, new_data), text) – Данияр Супиев Sep 29 '13 at 15:37
  • words = dict(zip(old_data, new_data)); text = regex.sub(r'\b\L<words>\b', lambda m: words[m.group()], text, words=words)' – jfs Mar 19 '18 at 07:58
0

Если есть функция, которая производит замену слов в строке:

import regex  # pip install regex

def new_text(old_text, words=dict(zip(old_data, new_data))):
    return regex.sub(r'\b\L<words>\b', lambda m: words[m.group()], old_text,
                     words=words)

то задача сводится к замене строк, используя эту функцию. К примеру:

from pathlib import Path

path = Path(filename)
path.write_text(new_text(path.read_text()))

Чтобы не загружать весь файл целиком в память, можно построчно замену производить. См. Как заменить строчку в .txt файле через python 3?

jfs
  • 52,361