将数据从逐行打印更改为列表(在文本文件中)

时间:2016-01-23 12:49:24

标签: python list dictionary

我正在使用python,空闲版本3.4.2 打印时我的代码,每个名称打印3个分数,但它们打印如下:

Maya: 3
Maya:2
Maya: 4

我想知道是否有任何方法可以让它在列表/字典中打印出来,这样我可以稍后调用分数进行排序

Maya = [3,2,4]

这是我的代码。

students_names = []
import random #import module
print("What is your name?") #prints writing in brackets
name = input().title() #Capitalizes the first letter of the word inputted
students_names.append(name)

print("What class are you in? (Enter 1, 2 or 3)") #asks the user to input a number

while True:
   try:
       class_number = int(input()) #asks for an integer input from user
   except ValueError: 
       print("Sorry, I didn't understand that, please try again") #print statement
       continue

   if class_number > 3: #if input is more than 3
       print("SORRY but that class isn't recognised, try again") #print statement
       continue
   else:
       print ("Hello,", name, "from class", class_number, "welcome to my quiz") #prints writing in brackets and anything saved in the variable "name" and "class_number"
       break #break out of loop

score = 0  #sets the variable "score" to zero
question = 0 # sets the variable "question" to zero
print(class_number)

while question < 3:#If questions (intitally set to 0) is smaller than 10, carry out this function
   question +=1 # add one to the value of "question"
   maths = random.randint(1,3) #randomly generate a number from 1-3 and store as "maths"
   num1 = random.randint(1,10)#randomly generate an integer from 1-10 and store as "num1"
   num2 = random.randint(1,10)#randomly generate a second integer from 1-10 and store as "num2"
   if maths == 1: #if the number generated is 1 
       print(num1, "+", num2) #prints num1 + num2
       ans = num1 + num2 #sets "ans" to equal the value of num1 added to num2

   elif maths == 2: #if the number generated is 1
       print(num1, "*", num2) #print num1 multiplied by num2
       ans = num1 * num2 #sets "ans" to equal the value of num1 multiplied by num2

   else: #else run this part of code
       print(num1, "-", num2) #print num1 subtracted by num2
       ans = num1 - num2 #sets "ans" to equal the value of num1 subtracted by num2

   while True:
       try:
           user_ans = int(input()) #user inputs answer to question
       except ValueError: #runs when the user input is no an integer
           print ("SORRY but that answer isn't recognised, try again")
       else:
           break


   if user_ans == ans:
       score+=1
       print("Well done, you are CORRECT")

   else:
       print("SORRY, you are INCORRECT") #print writing in brackets
       print("The correct answer was", ans)

if score == 10: #run this part of code if "score" equals 10
       print("fantastic", name, "you got full marks!")#print statement and name 
elif score >= 6: #run this part of code if "score" is larger than or equal to 6
       print("well done, there's some improvement to be done here though", name, "you got", score, "/10")# then print statement and score
elif score <=5: #run this part of code if "score" is smaller than or equal to 5
       print("hmm, maybe some more practise would be beneficial", name, "you got", score, "/10") #then print statement and score

class_number = str(class_number) + ".txt" #this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
file = open(class_number, 'a') #opens the file in 'append' mode so you don't delete all the information
file.write(str(students_names))
file.write(str(name + " : ")) #writes the name and ":" to file
file.write(str(score)) #writes the score to file
file.write('\n')#writes the score to the file
file.close()#safely closes the file to save the information

2 个答案:

答案 0 :(得分:0)

当然,只需将人物的得分值添加到新词典中即可。

name_dict = {}

if name in name_dict:
   name_dict[name].append(new_score)
else:
   name_dict[name] = [new_score]

跟进代码有点困难。因此,我无法完全整合它。

答案 1 :(得分:0)

好的,我想我得到了你正在寻找的东西。但为了简化我对此的回答,我们首先需要简化您的示例。一个好方法是将代码切换成函数:

如何存储结果?

首先,我们会查看您需要帮助的位置,这是您的代码的最后一位,它适合我们称之为store_results()的函数:

 def store_results(...):
      class_number = str(class_number) + ".txt" # this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
      file = open(class_number, 'a') # opens the file in 'append' mode so you don't delete all the information
      file.write(str(students_names))
      file.write(str(name + " : ")) # writes the name and ":" to file
      file.write(str(score)) # writes the score to file
      file.write('\n') # writes the score to the file
      file.close() # safely closes the file to save the information

我在这里使用...作为函数的参数,这不是python,可以考虑它。该函数需要什么参数才能正常工作?

  • class_number:学生回答质量保证的班级在
  • name:学生在质量保证中的得分
  • student_names

您在此处所做的是,当您运行该代码时,您将附加name 进入student_names,它将始终包含一个,只有一个名称。所以当 你为file.write(str(students_names))的用户写John,你就是&#l; ll 最后写作:

...
['John']
John : 5
...

这不是我相信你期待的东西。实际上你根本不需要那个列表。

所以作为第一次更新,你应该这样做:

 def store_results(class_number, name, score):
      class_file = "{}.txt".format(class_number)  # this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
      with open(class_file, 'a') as f: # opens the file in 'append' mode so you don't delete all the information
           f.write("{}: {}\n".format(name, score) # outputs the user's score to the file

该代码段中的其他更改包括: - 您不应将file用作变量,因为它已作为全局类型存在,并在其中使用 你的代码被认为是不好的做法叫做&#34;影子&#34;这可能导致很难找到错误 (不是在这种情况下,但是如果你现在不养成良好的习惯,它会在未来的代码中咬你)。 - 您应使用with open() as f:构造而不是手动打开和关闭文件, 因为在您现有的代码中,如果在openclose之间引发了异常 文件未被正确关闭,最终可能会丢失写入。 - 你应该使用格式字符串而不是直接字符串连接,这就是代码 更容易阅读和修改。

现在,正如所说的那样,您仍然会遇到每个测试结果的问题 由用户显示为:

John: 2
John: 4
John: 5

解决这个问题的正确方法是不要使用&#34; blinded&#34;附加到文件,而是 使用该文件作为某种非常基本的数据库。最简单的选择是 在JSON文件中编写您的分数,该文件在语法上与python兼容 (对手动测试非常有用):

import os
import json

def store_results(class_number, name, score):
    # this adds '.json' to the end of the file (therefore creating a json file)
    class_file = "{}.json".format(class_number)

    # first step: load the existing data

    # first test if the file exists, and if not, use an empty score dictionary
    if not os.path.exists(class_file):
        scores = {}
    # otherwise populate the dictionary
    else:
        # open as read only, because we just want the data out of it
        with open(class_file, 'r') as f:
            # load contents of the json file "f" as object "scores"
            scores = json.load(f)

    # second step: update the data

    scores.setdefault(name, []).append(score)

    # third step: update the file

    # use 'w' when opening the file to overwrite all data within it
    with open(class_file, 'w') as f:
        # dump object "scores" within file "f"
        json.dump(scores, f)

在这段代码中,我使用了一个技巧来将分数插入一行:

scores.setdefault(name, []).append(score)

相当于:

# if the user's "name" is not already in the dictionary
if name not in scores.keys():
    # add it as a new key containing an empty list
    scores[name] = []
# append the "score" to the list indexed by the user's "name"
scores[name].append(score)

然后文件中的结果如下:

{"John":[3,5,10],"Jane":[2],"Bob":[1,0,2]}

要使输出文件更具可读性,您可以将json.dump行更改为:

json.dump(scores, f, sort_keys=True, indent=4, separators=(',', ': '))

将输出:

{
    "Bob": [
        1,
        0,
        2
    ],
    "Jane": [
        2
    ],
    "John": [
        3,
        5,
        10
    ]
}

如何运行QA?

最后,您要创建另一个处理QA过程的函数 你调用我们刚刚定义的函数

# add the following import at the start of your script if you're running python2 and not python3
from __future__ import print_function

def run_qa():
    print("What is your name?") # prints writing in brackets
    name = input().title() # Capitalizes the first letter of the word inputted

    print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number

    while True:
        try:
            class_number = int(input()) # asks for an integer input from user
        except ValueError: 
            print("Sorry, I didn't understand that, please try again") # print statement
            continue

        if class_number > 3: # if input is more than 3
            print("SORRY but that class isn't recognised, try again") # print statement
            continue
        else:
            break # break out of loop

    # prints writing in brackets and anything saved in the variables "name" and "class_number"
    print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))

    score = 0  # sets the variable "score" to zero
    question = 0 # sets the variable "question" to zero

    while question < 3: # If questions (initially set to 0) is smaller than 10, carry out this function
        question += 1 # add one to the value of "question"
        maths = random.randint(1,3) # randomly generate a number from 1-3 and store as "maths"
        num1 = random.randint(1,10) # randomly generate an integer from 1-10 and store as "num1"
        num2 = random.randint(1,10) # randomly generate a second integer from 1-10 and store as "num2"
        if maths == 1: # if the number generated is 1
            print("{} + {} = ?".format(num1, num2)) # prints num1 + num2
            ans = num1 + num2 # sets "ans" to equal the value of num1 added to num2

        elif maths == 2: # if the number generated is 1
            print("{} * {} = ?".format(num1, num2)) # print num1 multiplied by num2
            ans = num1 * num2 # sets "ans" to equal the value of num1 multiplied by num2

        else: # else run this part of code
            print("{} - {} = ?".format(num1, num2)) # print num1 subtracted by num2
            ans = num1 - num2 # sets "ans" to equal the value of num1 subtracted by num2

        while True:
            try:
                # print a nice little prompt for the user to enter his answer
                print("> ", end="")
                user_ans = int(input()) # user inputs answer to question
                # if an exception is raised by "int()" the break is not being called
                # here you achieve the same as a single line, as you're doing in two
                # lines with your try/except/else clause, making your code more readable.
                break
            except ValueError: # runs when the user input is no an integer
                print ("SORRY but that answer isn't recognised, try again")


        if user_ans == ans:
            score += 1
            print("Well done, you are CORRECT")

        else:
            print("SORRY, you are INCORRECT") # print writing in brackets
            print("The correct answer was {}".format(ans))

    if score == 10: # run this part of code if "score" equals 10
         print("Fantastic {}, you got full marks!".format(name))# print statement and name
    elif score >= 6: # run this part of code if "score" is larger than or equal to 6
         print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))#  then print statement and score
    elif score <=5: # run this part of code if "score" is smaller than or equal to 5
         print("hmm, maybe some more practice would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score

    # return the results
    return class_number, name, score

最后,要调用代码,只需在脚本末尾添加以下内容:

if __name__ == "__main__":
    class_number, name, score = run_qa()
    store_results(class_number, name, score):

if语句的原因是为了以后可以包含你的代码 另一个模块中的模块没有运行它,这被认为是一种很好的做法!

作为另一项改进,我避免多次重复相同的代码来检查输入 来自用户,但改为使用函数:

def get_integer_input(maxval=None):
    while True:
        try:
            # print a nice prompt
            print("> ", eol="")
            i = int(input()) # asks for an integer input from user
            if maxval:
                if i >= maxval:
                    continue
                    print("Sorry, input shall be inferior than {}, try again".format(maxval))
            break
        except ValueError:
            print("Sorry, I didn't understand that, please try again") # print statement

    return i

然后在你的代码中使用它:

...
class_number = get_integer_input(maxval=3)
...

BTW,作为一项改进,我实际上将run_qa拆分为两个函数:一个 生成问题,另一个生成交互过程。

这样你就可以:

if __name__ == "__main__":
    questions = generate_qa()
    class_number, name, score = run_qa(questions)
    store_results(class_number, name, score)

generate_qa()类似:

def generate_qa():
    questions = []
    while len(questions) < 3: # add a question until we have three generated
        op = random.randint(0,2) # randomly generate a number from 1-3 and store as "maths"
        num1 = random.randint(1,10) # randomly generate an integer from 1-10 and store as "num1"
        num2 = random.randint(1,10) # randomly generate a second integer from 1-10 and store as "num2"
        questions.append( (op, num1, num2) )
    return questions

然后:

def run_qa(questions):
    print("What is your name?") # prints writing in brackets
    name = input().title() # Capitalizes the first letter of the word inputted
    print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
    class_number = get_integer_input(maxval=3)

    # prints writing in brackets and anything saved in the variables "name" and "class_number"
    print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))

    score = 0  # sets the variable "score" to zero

    for op, left, right in questions:
        if op == 0: # if the number generated is 0
            op("{} + {} = ?".format(left, right)) # prints 'left' + 'right'
            ans = left + right # sets "ans" to equal the value of num1 added to 'right'

        elif op == 1: # if the number generated is 1
            print("{} * {} = ?".format(left, right)) # print 'left' multiplied by 'right'
            ans = left * right # sets "ans" to equal the value of num1 multiplied by 'right'

        else: # the only possible value is: op == 2
            print("{} - {} = ?".format(left, right)) # print 'left' subtracted by 'right'
            ans = left - right # sets "ans" to equal the value of num1 subtracted by 'right'

        user_ans = get_integer_input()

        if user_ans == ans:
            score += 1
            print("Well done, you are CORRECT")

        else:
            print("SORRY, you are INCORRECT") # print writing in brackets
            print("The correct answer was {}".format(ans))

    if score == 10: # run this part of code if "score" equals 10
         print("Fantastic {}, you got full marks!".format(name))# print statement and name
    elif score >= 6: # run this part of code if "score" is larger than or equal to 6
         print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))#  then print statement and score
    elif score <=5: # run this part of code if "score" is smaller than or equal to 5
         print("hmm, maybe some more practise would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score

    return class_number, name, score

最后,可以对代码进行的最后一项改进是使用包含运算符的dict:

import operator

operations = {
    '+': operator.add,
    '*': operator.mul,
    '-': operator.sub
}

然后您按如下方式简化run_qa

def run_qa(questions):
    print("What is your name?") # prints writing in brackets
    name = input().title() # Capitalizes the first letter of the word inputted
    print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
    class_number = get_integer_input(maxval=3)

    # prints writing in brackets and anything saved in the variables "name" and "class_number"
    print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))

    score = 0  # sets the variable "score" to zero

    for op, left, right in questions:
        # convert from index value into symbol (the "list()" is a needed trick for python3
        op = list(operations.keys())[op]
        print("{} {} {} = ?".format(left, op, right))

        # calculate the operation with operator 'op' using 'left' and 'right'
        ans = operations[op](left, right)

        user_ans = get_integer_input()

        if user_ans == ans:
            score += 1
            print("Well done, you are CORRECT")

        else:
            print("SORRY, you are INCORRECT") # print writing in brackets
            print("The correct answer was {}".format(ans))

    if score == 10: # run this part of code if "score" equals 10
         print("Fantastic {}, you got full marks!".format(name))# print statement and name
    elif score >= 6: # run this part of code if "score" is larger than or equal to 6
         print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))#  then print statement and score
    elif score <=5: # run this part of code if "score" is smaller than or equal to 5
         print("hmm, maybe some more practice would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score

    return class_number, name, score

Nota Bene :我没有在本地测试我的代码,它已经在答案框中进行了实时编码 stackoverflow,所以可能存在语法错误和可能是小错误。的目标 我的回答是强调你做错了什么,并告诉你如何做得更好。所以, 请不要带它&#34;按原样#34;复制/粘贴,但通读,了解我的意思 向您展示,并根据我给您的改进更新您的代码。

这是我刚刚测试过的完整示例:

# make the script both py2 and py3 compatible
from __future__ import print_function
import sys
if sys.version_info.major == 2:
    input = raw_input

import operator
import random
import json
import os


def store_results(class_number, name, score):
    # this adds '.json' to the end of the file (therefore creating a json file)
    class_file = "{}.json".format(class_number)

    # first step: load the existing data

    # first test if the file exists, and if not, use an empty score dictionary
    if not os.path.exists(class_file):
        scores = {}
    # otherwise populate the dictionary
    else:
        # open as read only, because we just want the data out of it
        with open(class_file, 'r') as f:
            # load contents of the json file "f" as object "scores"
            scores = json.load(f)

    # second step: update the data

    scores.setdefault(name, []).append(score)

    # third step: update the file

    # use 'w' when opening the file to overwrite all data within it
    with open(class_file, 'w') as f:
        # dump object "scores" within file "f"
        json.dump(scores, f, sort_keys=True, indent=4, separators=(',', ': '))

def get_integer_input(maxval=None):
    while True:
        try:
            # print a nice prompt
            print("> ", end="")
            i = int(input()) # asks for an integer input from user
            if maxval:
                if i >= maxval:
                    continue
                    print("Sorry, input shall be inferior than {}, try again".format(maxval))
            break
        except ValueError:
            print("Sorry, I didn't understand that, please try again") # print statement

    return i

operations = {
    '+': operator.add,
    '*': operator.mul,
    '-': operator.sub
}

def generate_qa():
    questions = []
    while len(questions) < 3: # add a question until we have three generated
        op = random.randint(0,2) # randomly generate a number from 1-3 and store as "maths"
        num1 = random.randint(1,10) # randomly generate an integer from 1-10 and store as "num1"
        num2 = random.randint(1,10) # randomly generate a second integer from 1-10 and store as "num2"
        questions.append( (op, num1, num2) )
    return questions

def run_qa(questions):
    print("What is your name?") # prints writing in brackets
    name = input().title() # Capitalizes the first letter of the word inputted
    print("What class are you in? (Enter 1, 2 or 3)") # asks the user to input a number
    class_number = get_integer_input(maxval=3)

    # prints writing in brackets and anything saved in the variables "name" and "class_number"
    print ("Hello, {} from class {} welcome to my quiz".format(name, class_number))

    score = 0  # sets the variable "score" to zero

    for op, left, right in questions:
        # convert from index value into symbol (the "list()" is a needed trick for python3
        op = list(operations.keys())[op]
        print("{} {} {} = ?".format(left, op, right))
        # calculate the operation with operator 'op' using 'left' and 'right'
        ans = operations[op](left, right)

        user_ans = get_integer_input()

        if user_ans == ans:
            score += 1
            print("Well done, you are CORRECT")

        else:
            print("SORRY, you are INCORRECT") # print writing in brackets
            print("The correct answer was {}".format(ans))

    if score == 10: # run this part of code if "score" equals 10
            print("Fantastic {}, you got full marks!".format(name))# print statement and name
    elif score >= 6: # run this part of code if "score" is larger than or equal to 6
            print("Well done, there's some improvement to be done here, though {} you got {}/10".format(name, score))#  then print statement and score
    elif score <=5: # run this part of code if "score" is smaller than or equal to 5
            print("hmm, maybe some more practise would be beneficial, {}, you got {}/10".format(name, score)) # then print statement and score

    return class_number, name, score

if __name__ == "__main__":
    questions = generate_qa()
    class_number, name, score = run_qa(questions)
    store_results(class_number, name, score)

HTH