在循环字典时使用.replace() - 为什么代码1不起作用而代码2不起作用?

时间:2014-01-19 06:12:47

标签: python dictionary text-files

你好:我有点像编程/蟒蛇新手。我刚刚尝试创建一个循环遍历字典的简单脚本,并将字典键替换为文本文件中文本的关联值。我的第一个代码不起作用,我不明白为什么。这是

replacements = {'Bob': 'John', 'Betty': 'Brenda'}

def main():
    with open('end_words_list.txt', 'r+') as article:
        read_article = article.read()
        for ending, replacement in replacements.iteritems():
            replaced = read_article.replace(ending, replacement)
            article.seek(0)
            article.write(replaced)

if __name__ == '__main__':
    main()

此代码在运行ValueError: I/O operation on closed file时会出现此错误。

所以我决定用2个函数重写代码,在这个函数中我将字典循环与实际写入文件分开,看看是否有效。它确实如此。这是代码:

replacements = {'Bob': 'John.', 
                'Betty': 'Brenda'}

def search_and_replace(ending, replacement):
    with open('end_words_list.txt', 'r+') as article:
        read_article = article.read()
        replaced = read_article.replace(ending, replacement)
        article.seek(0)
        article.write(replaced)

def main():
    for ending, replacement in replacements.iteritems():
        search_and_replace(ending, replacement)


if __name__ == '__main__':
    main()

然而,我仍然感到困惑,为什么第一个代码不起作用。当代码与第二个代码中的代码非常相似时,为什么在尝试写入时文本文件被视为已关闭?

编辑:oops在写入之前忘记添加文本文件的内容:

I got a friend called Bob, and a friend called Betty. Bob is nice, but Betty is nicer.

编辑2:添加完整的追溯

Traceback (most recent call last):
[Finished in 0.1s with exit code 1]  File "D:\Magic Briefcase\My Python Scripts\Spin Scripts\End Words\End_Words.py", line 12, in <module>
    main()
  File "D:\Magic Briefcase\My Python Scripts\Spin Scripts\End Words\End_Words.py", line 8, in main
    article.seek(0)
ValueError: I/O operation on closed file

2 个答案:

答案 0 :(得分:2)

问题是你在代码中混合了标签和空格,所以对你来说看起来像是正确的缩进看起来与翻译完全不同。

特别是,您对main函数的前两行使用了制表符,但其余部分则使用空格。因为解释器将制表符视为缩进8个空格(与StackOverflow不同,并且可能是您的编辑器,将它们视为缩进4个空格,或者跳转到下一个制表位),它会看到您的代码如下:

def main():
        with open('end_words_list.txt', 'r+') as article:
                read_article = article.read()
        for ending, replacement in replacements.iteritems():
            replaced = read_article.replace(ending, replacement)
            article.seek(0)
            article.write(replaced)

如果您使用Notepad或TextEdit等编辑器,请切换到其他任何内容。大多数其他编辑器都可以将所有标签转换为空格,或明确显示标签,或以其他方式解决此问题。

此外,尝试使用-tt标志运行代码,当它检测到您意外地从标签切换到空格或反之亦然时,会给您一个明确的错误,而不是默默地误解您的代码。

答案 1 :(得分:1)

abarnert的回答是正确的(我很确定它始终是:)),但我还想解决另外两个问题:

  • 在您替换所有这些内容之前,无需将replaced写回article。把它从for循环中取出来。

  • 您一次更换一个单词,将其保存到变量中,然后替换原始字符串中的下一个单词而不是更新。每次修改相同的变量,将其存储到位,以便为下一次迭代做好准备。

所以你的代码应该是:

def main():
    with open('end_words_list.txt', 'r+') as article:
        read_article = article.read()
        for ending, replacement in replacements.iteritems():
            read_article = read_article.replace(ending, replacement)
        article.seek(0)
        article.write(read_article)

请注意,我已将作业从replaced更改为read_article,并且我已将seekwrite排除在循环之外。