简体   繁体   English

Python将字典覆盖字典转换为文本文件不起作用…为什么?

[英]Python Overwrite Dictionary to Text File doesn't work… why?


I've been previously writing code for a quiz program with a text file that stores all of the participants' results. 我以前一直在用一个文本文件编写一个测验程序的代码,该文件存储了所有参与者的结果。 The code that converts the text file to a dictionary and the text file itself are shown below: 将文本文件转换成字典的代码以及文本文件本身如下所示:

Code: 码:

import collections
from collections import defaultdict
scores_guessed = collections.defaultdict(lambda: collections.deque(maxlen=4))
with open('GuessScores.txt') as f:
    for line in f:
        name,val = line.split(":")
        scores_guessed[name].appendleft(int(val))

for k in sorted(scores_guessed):
    print("\n"+k," ".join(map(str,scores_guessed[k])))

writer = open('GuessScores.txt', 'wb')

for key, value in scores_guessed.items():       
    output = "%s:%s\n" % (key,value)
    writer.write(output)

The text file appears like this: 文本文件如下所示:

Jack:10
Dave:20
Adam:30
Jack:40
Adam:50
Dave:60
Jack:70
Dave:80
Jack:90
Jack:100
Dave:110
Dave:120
Adam:130
Adam:140
Adam:150

Now, when I run the program code, the dictionary appears like this: 现在,当我运行程序代码时,字典如下所示:

Adam 150 140 130 50

Dave 120 110 80 60

Jack 100 90 70 40

Now, this arranges the dictionary into order of highest scores, and the top 4 scores! 现在,这将字典按最高分和最高4分的顺序排列!

I want the python IDLE to overwrite the GuessScores.txt to this: 我想要python IDLE覆盖GuessScores.txt到此:

Adam:150
Adam:140
Adam:130
Adam:50
Dave:120
Dave:110
Dave:80
Dave:60
Jack:100
Jack:90
Jack:70
Jack:40

BUT when I run the code, this error appears: 但是当我运行代码时,出现此错误:

Traceback (most recent call last):
  File "/Users/Ahmad/Desktop/Test Files SO copy/readFile_prompt.py", line 16, in <module>
    writer.write(output)
TypeError: 'str' does not support the buffer interface

The GuessScores.txt file is empty because it cannot write to the file, since there is the error above. 由于上面存在错误,因此GuessScores.txt文件为空,因为它无法写入该文件,因此为空。

Why is this happening? 为什么会这样呢? And what is the fix? 解决方法是什么? I have asked this previously but there were numerous issues. 我以前曾问过这个问题,但是有很多问题。 I am running Python 3.3.2 on a Mac 10.8 Mavericks iMac, if that makes any help. 我在Mac 10.8 Mavericks iMac上运行Python 3.3.2,如果有帮助的话。

Thanks, Delbert. 谢谢,德尔伯特。

The first issue is that you are trying to write text to a file that you opened in binary mode. 第一个问题是您试图将文本写入以二进制模式打开的文件。 In 3.x, this will no longer work. 在3.x中,它将不再起作用。 "text" vs. "binary" used to mean very little (only affecting line-ending translation, so no difference at all on some systems). “文本”与“二进制”之间的含义很少(仅影响行尾翻译,因此在某些系统上完全没有区别)。 Now it means like what it sounds like: a file opened in text mode is one whose contents are to be treated like text with some specific encoding, and a file opened in binary mode is one whose contents are to be treated as a sequence of bytes. 现在,它的含义听起来像是:以文本模式打开的文件是将其内容视为具有某种特定编码的文本的文件,以二进制模式打开的文件是将其内容视为字节序列的文件。 。

Thus, you need open('GuessScores.txt', 'w') , not open('GuessScores.txt', 'wb') . 因此,您需要open('GuessScores.txt', 'w') ,而不是open('GuessScores.txt', 'wb')

That said, you really should be using with blocks to manage the files, and you're going to have to write code that actually formats the dictionary content in the way you want. 这就是说,你真的应该使用with块管理的文件,你将不得不写,其实格式化你想要的方式词典内容的代码。 I assume you intend to output in sorted name order, and you need to iterate over each deque and write a line for each item. 我假设您打算按已排序的名称顺序输出,并且需要遍历每个双端队列并为每个项目写一行。 Something like: 就像是:

with open('GuessScores.txt', 'w') as f:
    for name, scores in sorted(scores_guessed.items()):
        for score in scores:
            f.write("{}:{}\n".format(name, score))

(Note also the new-style formatting.) (另请注意新样式的格式。)

If necessary, you can explicitly specify the encoding of the file in the open call, with the encoding keyword parameter. 如有必要,您可以使用encoding关键字参数在open调用中显式指定文件的encoding (If you don't know what I mean by "encoding", you must learn. I'm serious. Drop everything and look it up.) (如果您不了解“编码”的含义,则必须学习。我是认真的。删除所有内容并查找它。)

The writing problem has to do with the b in your open function. 书写问题与open函数中的b有关。 You've opened it in binary mode, so only bytes can be written. 您已以二进制模式打开它,因此只能写入字节。 You can either remove the b or call bytes on output to give it the right type. 您可以删除b或在output上调用bytes以为其提供正确的类型。 You have a logic error anyway though. 无论如何,您还是有逻辑错误。 When I run it on Python 2.7, the output to GuessedScores.txt is this: 当我在Python 2.7上运行它时,GuessedScores.txt的输出是这样的:

Dave:deque([120,110,80,60],maxlen=4) 戴夫:双端队列([120,110,80,60],MAXLEN = 4)
Jack:deque([100, 90, 70, 40], maxlen=4) 杰克:deque([100,90,70,40],maxlen = 4)
Adam:deque([150, 140, 130, 50], maxlen=4) Adam:deque([150,140,130,50],maxlen = 4)

So your values are the whole deques, not the individual scores. 因此,您的价值观是整个双端队列,而不是个人分数。 You'll have to format them, similar to how you did in your print statement. 您必须对它们进行格式化,类似于在打印语句中进行的格式化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM