gpt4 book ai didi

python - Python 列表的问题

转载 作者:行者123 更新时间:2023-11-28 22:00:42 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:




9年前关闭。




Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument



好的,所以我正在尝试学习 Python。几个学期前,我有一个 friend 上过 Python 类(class)的介绍,他把他所有的旧作业都给了我。我有一个特别烦人的问题,我认为应该很简单,但似乎无法弄清楚我的问题出在哪里。看看大家怎么想的。

该程序应该从名为 grades.txt 的文件中读取。这是文件:
2
John Doe
82
100
57
0
Jane Smith
91
12
45
81
0

这个文件的格式是:第一行是学生人数。然后是学生的名字和他们的成绩。零表示学生成绩列表的结束。我知道,我知道……这样做没有多大意义,但这就是它的阅读方式。

无论如何,这是我到目前为止为它编写的代码......
#!/usr/bin/env python

class students():
def __init__(self, fname='', lname='', grades=[]):
self.firstName = fname
self.lastName = lname
self.gradeBook = grades

def lineCheck(lineText):
try:
int(lineText)
return True
except ValueError:
return False

inFile = "grades.txt"
outFile = "summary.txt"

count = 0
numStudents = 0

studentList = []
check = False

with open(inFile, "r") as file:
for line in file:
if(count == 0):
numStudents = line.strip()
else:
lineRead = line.strip()
check = lineCheck(lineRead)
if(check == False):
studentName = lineRead.split()
fName = studentName[0]
lName = studentName[1]
temp = students(fName, lName)
else:
if(lineRead != '0'):
temp.gradeBook.append(lineRead)
elif(lineRead == '0'):
studentList.append(temp)

count += 1
file.close()

for student in studentList:
print student.firstName + " " + student.lastName
print student.gradeBook

使用此代码,我的预期输出是在最终 for 循环中的程序末尾。我希望看到这样的事情:
John Doe
['82', '100', '57']
Jane Smith
['91', '12', '45', '81']

但是,我得到的输出是这样的:
John Doe
['82', '100', '57', '91', '12', '45', '81']
Jane Smith
['82', '100', '57', '91', '12', '45', '81']

我已经盯着这个太久了,我觉得这很简单。但由于我是 python 新手,还没有完全习惯它的所有细微差别,也许有经验的人可以找出这里发生的事情。我真的很感激你能给我的任何帮助。谢谢。

最佳答案

您的实际问题是您正在使用 []作为默认参数。默认参数创建一次并“附加”到函数中,因此每次创建新的学生对象时,都会重复使用相同的成绩列表。你想要这样的东西:

def __init__(..., grades=None):
if grades is None:
self.gradeBook = []
else:
self.gradeBook = grades

现在,请允许我给你一些其他的批评。 :)

看起来您的代码中包含空格和制表符的组合;在像 Python 这样的语言中,空格很重要,这真的很糟糕。我不知道您使用的是什么编辑器,但您应该了解如何配置它,因此按 Tab 始终会插入四个空格。

其余的内容不太重要,但它会帮助您与其他 Python 程序员相处,并且可能会帮助您的代码变得更简单。

您可以在几个地方执行此操作:
if(check == 0):

括号是不必要的。
if check == 0:

您有以下内容:
if(lineRead != '0'):
...
elif(lineRead == '0'):
...

但其中只有一个可能是真的——它要么相等,要么不相等——所以你不妨替换 elif ...。与 else .但这会导致双重否定(它不是 != ...),所以让我们交换分支。
if lineRead == '0':
...
else:
...
check = lineCheck(lineRead)
if(check == False):

您只使用 check变量一次,所以不需要它。此外,更常见的是避免与 True 进行比较。或 False直接地:
if not lineCheck(lineRead):

不过,这读起来不太好。执行 Action 的函数最好命名为动词,而验证某些东西的函数(如这个)在命名为 is_whatever 时听起来不错。 .变量,你想像你用英语谈论它一样命名;您不会经常谈论“读取行”,但您可能会谈论“读取行”,甚至只是“行”。

哦,还有 Python style guide, PEP 8建议使用下划线而不是 camelCase。
if not is_numeric(line):

类名通常用大写 Camel 大写,并且应该是单数,因为它们描述了一种事物。 (“你有什么样的宠物?”“一只猫。”)而且你应该总是从 object 继承。 ,或者你会得到一个“旧式类”,它来自 Python 的早期,而且有点笨拙。

虽然我在做,但学生没有名字没有多大意义。虽然你会更好 not trying to split it into first and last .
class Student(object):
def __init__(self, name, grades=None):
...

现在没关系,但稍后将所有“主”代码放在一个名为 main 的函数中会很有帮助。然后运行它。这样,您可以导入 main来自其他代码(例如测试),而无需立即运行所有内容。
if __name__ == '__main__':
main()
__name__只是当前“模块”的名称,它被设置为特殊字符串 '__main__'如果您使用 python file.py 直接运行文件.

经过一番重重的吹毛求疵,我最终得到了这个:
class Student(object):
def __init__(self, name, grades=None):
self.name = name
if grades is None:
self.gradebook = []
else:
self.gradebook = grades

def is_numeric(s):
try:
int(s)
return True
except ValueError:
return False

def main(infile, outfile):
count = 0
num_students = 0

students = []

with open(infile, "r") as f:
for line in f:
line = line.strip()

if count == 0:
# This is the first line
num_students = int(line)
elif not is_numeric(line):
# Non-numbers are names of new students
cur_student = Student(line)
elif line == '0':
# Zero marks the end of a student
students.append(cur_student)
else:
cur_student.gradebook.append(line)

count += 1

for student in students:
print student.name
print student.gradebook

if __name__ == '__main__':
main("grades.txt", "summary.txt")

我做了一些上面没有提到的小事;我希望他们有意义。
  • file是内置函数的名称。 Python 将允许您使用该名称,但如果您稍后尝试使用内置名称,您会感到惊讶。我将其替换为 f ,这是一种常用的方式来指代仅打开一小段时间的文件。
  • 很难记住是什么temp方法!尽量不要给变量这样的名字。我把它改成了 cur_student ,其中“cur”是“current”的常见缩写。
  • 你不需要f.close() ; with block 为你做。这就是 with 的全部意义所在。 , 实际上。
  • 您调用line.strip()不管发生什么,所以我把它作为循环中的第一件事。这允许所有 if s 合并为一个,这样可以更轻松地了解正在发生的事情和时间。
  • 我添加了一些快速评论,因为正如您所指出的,这是一种非常奇怪的文件格式。

  • 如果这意味着什么的话,这更接近我的写作方式。

    总是很高兴看到有人新进入编程领域!希望你喜欢 Python :)

    关于python - Python 列表的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14374035/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com