Python中的“初始化”变量是什么意思?

13

虽然在Python中初始化变量并不是必要的,但我的教授还是让我们练习这个。我写了我的程序,它也可以正常工作,但当我尝试初始化一些变量时,在运行它时出现了错误消息。以下是我程序的第一部分:

def main():

    grade_1, grade_2, grade_3, average = 0.0
    year = 0

    fName, lName, ID, converted_ID = ""
    infile = open("studentinfo.txt", "r")
    data = infile.read()
    fName, lName, ID, year = data.split(",")
    year = int(year)

    # Prompt the user for three test scores

    grades = eval(input("Enter the three test scores separated by a comma: "))

    # Create a username

    uName = (lName[:4] + fName[:2] + str(year)).lower()
    converted_id = ID[:3] + "-" + ID[3:5] + "-" + ID[5:]
    grade_1, grade_2, grade_3 = grades

错误信息:

grade_1, grade_2, grade_3, average = 0.0

TypeError: 'float' object is not iterable

1
grade_1, grade_2, grade_3, average = 0.0, 0.0, 0.0, 0.0 - sobolevn
1
grade_1 = grade_2 = grade_3 = average = 0.0 - Kenji Noguchi
7
抱歉,您指的是练什么?在那节课上,您还练了什么其他不必要的东西吗? - TigerhawkT3
1
@TigerhawkT3 哈哈,这是为(如果)我们学习其他语言的课程做准备。 - Ovi
3
我希望Python课程涵盖Python,其他语言的策略应该在它们各自的课程中讲解... =\ - TigerhawkT3
https://effbot.org/zone/default-values.htm - Ciasto piekarz
7个回答

23

有几种方法可以为相等的变量赋值。

最简单的方法:

grade_1 = grade_2 = grade_3 = average = 0.0

使用解包:

grade_1, grade_2, grade_3, average = 0.0, 0.0, 0.0, 0.0

使用列表推导和解包:

>>> grade_1, grade_2, grade_3, average = [0.0 for _ in range(4)]
>>> print(grade_1, grade_2, grade_3, average)
0.0 0.0 0.0 0.0

20

我知道你已经接受了另一个答案,但是我认为更广泛的问题需要解决 - 编程风格适合当前语言。

是的,在Python中不需要'initialization',但是你所做的并不是初始化。这只是一种不完整和错误的初始化模仿,就像其他语言中实践的那样。静态类型语言中关于初始化的重要事情是你指定变量的性质。

在Python中,与其他语言一样,在使用变量之前需要给它们赋值。但是,在函数开始时给它们赋值并不重要,如果你给出的值与之后接收的值没有任何关系,甚至是错误的。这不是“initialization”,而是“reuse”。

我将对你的代码进行一些注释和修正:

def main():
   # doc to define the function
   # proper Python indentation
   # document significant variables, especially inputs and outputs
   # grade_1, grade_2, grade_3, average - id these
   # year - id this
   # fName, lName, ID, converted_ID 

   infile = open("studentinfo.txt", "r") 
   # you didn't 'intialize' this variable

   data = infile.read()  
   # nor this  

   fName, lName, ID, year = data.split(",")
   # this will produce an error if the file does not have the right number of strings
   # 'year' is now a string, even though you 'initialized' it as 0

   year = int(year)
   # now 'year' is an integer
   # a language that requires initialization would have raised an error
   # over this switch in type of this variable.

   # Prompt the user for three test scores
   grades = eval(input("Enter the three test scores separated by a comma: "))
   # 'eval' ouch!
   # you could have handled the input just like you did the file input.

   grade_1, grade_2, grade_3 = grades   
   # this would work only if the user gave you an 'iterable' with 3 values
   # eval() doesn't ensure that it is an iterable
   # and it does not ensure that the values are numbers. 
   # What would happen with this user input: "'one','two','three',4"?

   # Create a username 
   uName = (lName[:4] + fName[:2] + str(year)).lower()

   converted_id = ID[:3] + "-" + ID[3:5] + "-" + ID[5:]
   # earlier you 'initialized' converted_ID
   # initialization in a static typed language would have caught this typo
   # pseudo-initialization in Python does not catch typos
   ....

你是老师吗? :) 对不同方面的解释很好。 - Rohit Srivastava
我很高兴这个答案存在。在Python中,变量保存对对象的引用,因此您不需要为其分配内存。没有必要初始化变量以避免任何垃圾留驻内存。由于它是动态类型的,一个变量可以在一刻钟持有整数,在另一刻钟持有字符串,并且在另一个时刻同时持有整数、浮点数、字符串和函数的列表。因此,只需在第一次需要变量时给它赋值,然后什么都不用想了。重要的引用,“那不是'初始化',而是'重用'”。 - Reti43

14

问题在这一行 -

grade_1, grade_2, grade_3, average = 0.0

fName, lName, ID, converted_ID = ""

在Python中,如果赋值运算符的左侧有多个变量,则Python会尝试迭代右侧相同次数,并将每个迭代值顺序地分配给每个变量。变量grade_1、grade_2、grade_3和average需要三个0.0值,以便按顺序分配给每个变量。

您可能需要这样做 -

grade_1, grade_2, grade_3, average = [0.0 for _ in range(4)]
fName, lName, ID, converted_ID = ["" for _ in range(4)]

列表推导式 [0.0 for _ in range(4)] 可以被对象的浅拷贝替代:[0.0] * 4。注意:这是浅拷贝,因此在使用可变对象时要小心,例如 [[]] * 4 可能不是您想要的,因为它创建了 4 个指向同一个空列表的元素。 - ROJI

5

Python将等号(=)左边的逗号视为输入分隔符,对于返回元组的函数非常有用。

例如:

x,y = (5,2)

你想要做的是:
grade_1 = grade_2 = grade_3 = average = 0.0

虽然那可能不是最清晰的写法。

3
您正在请求使用单个浮点对象初始化四个变量,这当然是不可迭代的。您可以执行以下操作 -
  1. grade_1, grade_2, grade_3, grade_4 = [0.0 for _ in range(4)]
  2. grade_1 = grade_2 = grade_3 = grade_4 = 0.0
除非您想用不同的值来初始化它们。

当你使用range(4)时,不需要使用range(0,4),因为它会自动从0开始。此外,在Python 2.x中最好使用xrange以获得更好的内存使用效果。 - Anand S Kumar
我已经做出了更改,现在可以了吗? - hspandher

2
如果您想使用解构赋值,您需要与变量数量相同的浮点数:
grade_1, grade_2, grade_3, average = 0.0, 0.0, 0.0, 0.0

0
def grade(inlist):
    grade_1, grade_2, grade_3, average =inlist
    print (grade_1)
    print (grade_2)

mark=[1,2,3,4]
grade(mark)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接