#%% 赋值与重新赋值
= 1
a = 2
a print(a)
2
本章我们将会介绍Python中最基础、也最重要的构件:变量和常用数据类型。
完成本章学习后,你将能够:
int
整数 和 float
小数),用于进行数学计算。str
),用于处理文本信息,比如姓名、标题等。bool
),代表逻辑上的“真”与“假”,是程序做决策的基础。None
值。input()
函数让你的程序与用户进行简单的交互。学完这一章,你最少就能把Python当作一个非常强大的计算器和超级记事本来使用。这是后续学习更复杂数据分析任务的基础。
再次强调: 编程时,请务必确保所有的语法符号(如冒号 :
、引号 ""''
、括号 ()
、等号 =
等)都必须是英文符号,在英文状态下输入。这是初学者最常见的错误来源之一!
前面说过,Python(或者其他编程语言)中的变量,和你数学课上的x, y, z
是同类的概念。
正如前面的例子,Python使用等号=
来为一个变量赋值
#%% 赋值与重新赋值
= 1
a = 2
a print(a)
2
假如这个变量a
一开始不存在,那么赋值的同时,也会把这个变量创造出来。
所谓变量名,本质上只是一个“标签”。Python处理赋值a = 1
时,可以这样理解:
a
,Python就知道你指的是1。a = 2
时,Python又在内存中创建了一个地方存放2。接着,它把a
这张标签从1那里撕下来,贴到了2这个新地方。原来的1如果没其他标签了,之后可能会被Python清理掉(这部分我们暂时不用深究)。print(a)
时,Python就去看a标签现在贴在哪里,然后把那个地方的数据(现在是2)拿出来显示。”在Python中给变量起名字也需要遵守一些规则和约定:
必须遵守的规则:
_
)。不能包含空格、@
、$
、-
等特殊符号。age
, Age
, AGE
是三个不同的变量。示例:
student_id
, price1
, user_name
, _temporary_var
(以下划线开头是合法的)1st_place
(以数字开头)student id
(包含空格)customer-name
(包含连字符 -
,应使用下划线 _
)price$
(包含特殊符号 $
)可能遇到的错误:
如果你使用了非法的变量名,Python通常在你尝试给它赋值时就会报错,最常见的是 SyntaxError: invalid syntax
(语法错误:无效语法)。
推荐的约定(好习惯):
user_name
而不是 un
,用 final_score
而不是 fs
。_
分隔。例如:interest_rate
, customer_address
。if
, else
, for
, while
, def
, class
, import
, return
, True
, False
, None
, and
, or
, not
等等。如果你不小心用了关键字做变量名,也会得到 SyntaxError
。使用del语句
#%% 删除变量
= 1
a print(a) # 先确认a存在且值为1
del a
print(a) # 再次引用会出错
1
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[3186], line 5 3 print(a) # 先确认a存在且值为1 4 del a ----> 5 print(a) # 再次引用会出错 NameError: name 'a' is not defined
因为变量a
已经被我们删除了,所以你再次引用a
的时候,Python会告诉你,
NameError: name 'a' is not defined
NameError: name 'xxx' is not defined
这个错误要告诉你,xxx这个东西,python找不到。这可能是:
apple
,但输入成了appla
。vscode会有提示。稍微解释下第3点:
a = 1
语句之后,a
这个变量才会存在。.py
文件中,有a=1
这个语句,如果你不执行一次,内存中也不会有a
。这表示,你只是打开一个.py文件,其实交互环境里面还是什么都没有, 这个时候print(a)
,就会提示找不到a
。
这个错误非常常见,尤其是刚开始学的时候。遇到它,首先检查拼写,其次想想这行代码之前的相关赋值代码是否真的被运行过了。
Python是一个“动态语言”,即Python的变量的类型是在运行过程中决定,或者说可以在运行中改变:你对这个变量赋什么值,这个变量就是什么类型。
查看变量类型的函数是type()
例如
#%% 动态类型
= 1
a print(type(a))
= 'apple' # 这里为a赋值了一个字符串
a print(type(a))
<class 'int'>
<class 'str'>
显然,a
先是一个整型int<class 'int'>
,然后变成了一个字符串str<class 'str'>
。 这和我们的赋值顺序是一样的。类型后面会详细说
注意:Python的变量类型是动态确定的。变量的类型不一定能从名字看出来,这是出错的一大来源。
Python 3.x以后,数值类型有2种,整型int
,和浮点型float
。
顾名思义,整型可以理解为整数:
#%% 整型
= 1
a print(type(a))
<class 'int'>
而浮点型则可以理解为小数:
#%% 浮点型
= 1.23
a print(type(a))
<class 'float'>
特别地,a = 1.0
是什么类型?
= 1.0
a print(type(a))
<class 'float'>
显然,a
是浮点型:只要你赋值的时候有小数点。 这可能是因为:
1.0000001
之类。+, -, *, /
等等,此处不再重复。特别地,除法永远返回浮点类型:
= 4 / 2
a print(a)
print(type(a))
2.0
<class 'float'>
//
。若除数是整型,则返回整型;若除数是浮点型,则返回浮点型5 // 2
2
5 // 2.0
2.0
%
5 % 2
1
2 ** 3
8
求二元一次方程的根:
\[ 2x^2 + 5x - 3 = 0 \]
提示:求根公式是 \[ x = \frac{ -b \pm \sqrt{b^2 - 4ac} }{2a} \]
答案是(-3, 0.5)
创建字符串,可以使用单引号、双引号、三单引号和三双引号。其中三引号可以多行定义字符串。
#%% 字符串
= 'apple' # 或者:a = "apple"
a print(a)
apple
通常情况下,用单引号或双引号效果一样。选择哪个看个人习惯或团队规范。一个常见的做法是,如果字符串内部包含单引号,外部就用双引号,反之亦然,这样可以避免使用转义字符。” 例如:message = "He said 'Hello!'"
, reply = 'She replied "Hi!"'
= '''Hello
a Python
'''
print(a)
Hello
Python
特别的,多行字符串也可以充当多行的注释:只要你不把字符串赋予一个变量, 这串字符串就对你的程序逻辑没什么影响,这就成了另一种注释。
常用于在模块(.py)文件的开头或者函数(后面会说)的开头,但实际上任何地方都可以。
+
= 'Hello'
a = 'Python'
b print(a + b)
HelloPython
注:可以连加:a + b + c + d
= 'Hello Python'
a
print('lo' in a) # in: 是否存在
print(a.find('th') )# find():查找位置,从0开始计数,如果找不到会返回 -1。这里会输出 8 。
print(a.find('world')) # 输出 -1 (因为找不到)
print(a.replace('Python','Bob')) # replace():替换
print(a.lower()) # 转为小写:lower()
print(a.upper()) # 转为大写:upper()
print(" apple pie ".strip()) # 去除头尾的不可见字符(包括空格)
True
8
-1
Hello Bob
hello python
HELLO PYTHON
apple pie
后面讲列表List会详细介绍
\
\n
”print("Hello\nPython")
Hello
Python
这些字符,本身已经是Python语法的一部分,要放在字符串中显示,需要转义,即在这个符号之前加反斜杠,如你要显示双引号,则可以使用\"
。
print('反斜杠\\') # 反斜杠 \\
print('\"双引号\"') # 双引号 \'
print('\'单引号\'') # 单引号 \"
反斜杠\
"双引号"
'单引号'
如果一下子看不清楚,应该如何书写:
a = ' '
a = 'HelloWorld'
\n
= 'Hello\nWorld'
a print(a)
Hello
World
我们往往需要把一个变量插入一行字符中,例如我们想显示变量a
和b
的值
#%% 简单加法
= 1
a = 2
b = a + b
c print(a)
print(b)
print(c)
1
2
3
会得到:
1
2
3
但问题是,你只看结果,其实分不清哪个是a,哪个是b,哪个是c。所以,我们更想要的是一句话,如
a的值是: 1
b的值是: 2
c的值是: 3
所以要用到字符串格式化,把变量和字符串混合。
#%% 简单加法
= 1
a = 2
b = a + b c
print('a的值是:{}\nb的值是:{}'.format(a,b))
a的值是:1
b的值是:2
解释一下:
'a的值是:{}\nb的值是:{}'
,是一个字符串对象(object),注意两边的单引号。Str.format()
,是字符串类型的一个方法(method),也可以称之为“成员函数”:函数名+小括号。someone.do_something()
,某样东西做了一件什么事。Str.format()
,这个方法即一个“字符串格式化了自己”。具体的做法,是把format()
的参数,这里是a
和b
,按顺序填进原字符串中的大括号{}
中。\n
实际上,把字符串对象赋值给变量,如msg
,那么msg
就成了字符串类型(或者说指向了一个字符串对象),所以也可以这么做:
= 'a的值是:{}\nb的值是:{}'
msg print(msg.format(a,b))
a的值是:1
b的值是:2
还可以按参数的顺序(第一个元素是0):
= 'c的值是:{2}\na的值是:{0}\nb的值是:{1}'
msg print(msg.format(a,b,c))
c的值是:3
a的值是:1
b的值是:2
还有更简洁的办法”f-string”(需要python3.6版本或以上)
f
,形成f''
,即所谓”f-string”。= f'a的值是:{a}\nb的值是:{b}'
msg print(msg)
a的值是:1
b的值是:2
实际上,你要在中括号里放其他python语句,例如其中做运算,也可以
= f'a + b的值是{a + b}'
msg print(msg)
a + b的值是3
如果只是要显示一个变量的名称,还有更简单的办法(需要Python 3.8或以上)
f{变量名=}
print(f'{a=}')
a=1
简单的数字格式化:变量后加{变量名:格式}
如只显示2位小数:0.2f
= 3.1415926535897
pi print(f"圆周率(保留2位小数)是{pi:0.2f}")
圆周率(保留2位小数)是3.14
如以百分数形式显示:%
,保留2位小数是:.2%
= 0.25
z print(f"z是{z:.2%}")
z是25.00%
建立2个变量:name
和id
,分别赋值为你的姓名和学号。打印一个字符串,显示”学号:<你的学号>,姓名:<你的姓名>。”
圆的半径R=5
,计算圆的面积area
,并打印这句话,并保留2位小数:“半径为<圆的半径>的圆的面积是<圆的面积>”
input()
如果想要获得用户的输入,那么可以采用 input()
函数。
例1:获取名字并问候
input()
会暂停程序,显示括号里的提示信息(可选),等待用户输入并按回车。用户输入的内容会作为字符串返回。
# 下面这行会等待你输入名字
= input("请输入你的名字: ")
name # input返回的是字符串,可以直接和字符串 "+" 拼接
print("你好, " + name + "!")
# 或者使用 f-string (推荐)
print(f"你好, {name}!")
例2:获取出生年份计算大致年龄
关键点:input()
返回的永远是字符串 (str
) 类型! 即使用户输入的是数字,它也是字符串形式。如果想用这个输入进行数学计算,必须先转换类型。
= input("请输入你的出生年份: ")
birth_year_str # input返回的是字符串 'xxxx', 不能直接做减法
# 需要用 int() 将它转换成整数
= int(birth_year_str)
birth_year_int
= 2024 # 假设当前是2024年
current_year = current_year - birth_year_int
age
# 使用 f-string 输出结果
print(f"你今年大约 {age} 岁。")
在这个例子中,如果直接用 birth_year_str
去减,Python会报错 TypeError
。我们必须使用 int()
将表示年份的字符串(如 '2003'
)转换成真正的整数(如 2003
),然后才能进行减法运算。
总结:
input()
用于从用户获取输入,可以带提示信息。int()
或 float()
进行类型转换。这个问题后面我们还会更详细地讲解。。布尔型(Boolean,常简写为 bool)是编程中表示逻辑真假的数据类型。它非常简单,只有两个可能的值:
True
(真)False
(假)请特别注意: True
和 False
的首字母必须大写。
布尔值主要用在哪里呢?它们是程序进行决策的基础。比如,判断一个订单是否满足包邮条件:“如果订单金额大于100元,则包邮”——这里的“订单金额大于100元”就是一个需要判断真假的条件。要创建这些条件,我们最常使用的是比较运算符。
比较运算符用于比较两个值,然后返回一个布尔值 (True
或 False
) 来表示比较结果是否成立。
以下是Python中常用的比较运算符:
==
: 等于 (判断两边的值是否相等)
print(100 == 100) # True,因为 100 等于 100
print(100 == 99) # False,因为 100 不等于 99
print('apple' == 'apple') # True,字符串内容相同
print('Apple' == 'apple') # False,大小写不同
True
False
True
False
!=
: 不等于 (判断两边的值是否不相等)
print(100 != 99) # True,因为 100 确实不等于 99
print(100 != 100) # False,因为 100 等于 100
True
False
>
: 大于
print(101 > 100) # True
print(100 > 100) # False
True
False
<
: 小于
print(99 < 100) # True
print(100 < 100) # False
True
False
>=
: 大于等于
print(100 >= 100) # True
print(101 >= 100) # True
print(99 >= 100) # False
True
True
False
<=
: 小于等于
print(100 <= 100) # True
print(99 <= 100) # True
print(101 <= 100) # False
True
True
False
这些比较运算的结果,永远是一个布尔值 (True
或 False
)。
==
(比较) 与 =
(赋值) 的区别这是初学者最容易犯的错误之一!
=
(单个等号) 是 赋值运算符。它的作用是把右边的值 赋给 左边的变量。例如:order_amount = 150
是告诉Python,“把 150
这个值存到 order_amount
这个变量里”。==
(两个等号) 是 等于比较运算符。它的作用是 判断 两边的值是否相等,并返回 True
或 False
。例如:order_amount == 100
是问Python,“order_amount
变量里的值是不是等于 100
?”千万不要混淆! 在需要判断相等的地方错用了单个等号 =
会导致逻辑错误(有时甚至是 SyntaxError
)。
当我们有多个布尔条件时,可以用逻辑运算符 and
, or
, not
将它们组合起来:
与 and
:只有当 and
两边的条件都为 True
时,整个表达式的结果才为 True
;否则为 False
。(可以理解为“并且”)
= 120 # 订单金额
order_total = True # 是否是会员
is_member
# 条件:订单金额大于100 并且 是会员,才享受特殊折扣
= (order_total > 100) and (is_member == True)
qualify_special_discount print(f"订单金额 {order_total}, 是会员: {is_member}. 符合特殊折扣? {qualify_special_discount}") # True and True -> True
= (order_total < 100) and (is_member == True) # 金额不够,即使是会员也不行
qualify_example2 print(f"金额不够但会员? {qualify_example2}") # False and True -> False
订单金额 120, 是会员: True. 符合特殊折扣? True
金额不够但会员? False
或 or
:只要 or
两边的条件至少有一个为 True
时,整个表达式的结果就为 True
;只有两边都为 False
时,结果才为 False
。(可以理解为“或者”)
= False # 没有使用优惠券
has_coupon = True # 使用了积分兑换
points_redeemed
# 条件:使用了优惠券 或者 使用了积分兑换,订单总额可以减免
= has_coupon or points_redeemed
order_can_reduce print(f"使用优惠券: {has_coupon}, 使用积分: {points_redeemed}. 订单可减免? {order_can_reduce}") # False or True -> True
= has_coupon or False # 既没用券,也没用积分
order_cannot_reduce print(f"没用券也没用积分? {order_cannot_reduce}") # False or False -> False
使用优惠券: False, 使用积分: True. 订单可减免? True
没用券也没用积分? False
非 not
:对单个布尔值进行取反。not True
结果是 False
,not False
结果是 True
。
= True # 商品有库存
item_in_stock
# 如果商品不是没有库存 (即,有库存)
= not (item_in_stock == False) # not False -> True
can_purchase # 更简洁的写法是直接判断 True
= item_in_stock == True # True
can_purchase_simple # 或者更简洁 (因为 item_in_stock 本身就是布尔值)
= item_in_stock # True
can_purchase_simplest
print(f"商品有库存: {item_in_stock}. 可以购买? {can_purchase_simplest}")
print(f"not True 的结果是: {not True}") # False
print(f"not False 的结果是: {not False}") # True
商品有库存: True. 可以购买? True
not True 的结果是: False
not False 的结果是: True
(在 not
的例子中,展示了多种等价的判断方式,强调了可以直接使用布尔变量)
逻辑运算符也有执行的先后顺序:not
> and
> or
。 比较运算符 (>
, ==
等) 的优先级通常高于逻辑运算符。
但是,为了避免混淆和确保代码按你的意图执行,强烈建议使用括号 ()
来明确指定运算顺序! 就像在数学中一样。
例如,在 (order_total > 100) and (is_member == True)
中,括号确保了先进行 >
和 ==
的比较,得到两个布尔值后,再进行 and
运算。
空值,一切皆非。粗略地可以理解为一个“占位符”,例如一个不返回任何值的函数,以后遇到会再解释。
当你定义了一个变量,但暂时还没想好给它赋什么有意义的值时,可以先赋值为 None
。
= None
a print(a)
None
字符串:可以表示词语、句子,可以拼接,组合 数字:可以运算
数字可以拼接吗?字符串可以做运算吗?
先转换一下类型
= "2001"
birth
= 2021 - birth
age print(age)
TypeError: unsupported operand type(s) for -: 'int' and 'str'
NameError: name 'age' is not defined
一般而言,类型转换的函数,就是目标类型的名字。
把某个变量(如字符串str)转整型int,用函数int()
,转为浮点是float()
= "2001"
birth = 2021 - int(birth)
age print(age)
= 2021 - float(birth)
age print(age)
20
20.0
显然反过来转换也是可以的,把某个变量转为字符串str()
print('Your age is ' + str(age))
Your age is 20.0
需要注意的是,不是所有字符串都能成功转换成数字。比如,int('hello')
就会报错 ValueError
,因为 'hello'
无法被理解为整数。只有当字符串的内容确实能表示一个数字时,转换才能成功(例如 int('123')
,float('3.14')
)。
(有逻辑学基础,可以快速过)
特别地,布尔型中,True
可视为1
,False
可视为0
。 因此我们可以把数字的运算套用在布尔型上。
r red("注意")
:要保持代码的清晰性,一般不建议使用布尔型进行运算,除非你很明白自己在做什么。
= True # True可视为1
a print(a + 1)
= False # False可视为0
b print(b - 1)
2
-1
做条件判断的时候,0
会判定为False
,非0
会判断为True
,这个我们后面说条件语句的时候会说。
if -1:
print('hello')
hello
Python是一个“动态类型+强类型”语言
变量名运行时绑定,变量名只是一个可以撕掉和重新粘贴的标签。你为某个变赋值什么类型,这个变量就是什么类型,在运行时可以随你的赋值代码而改变。
一般情况下,Python不会为你自动转换类型(不会“隐式类型转换”)。
如一个很热门的语言JavaScript,大家现在上网看到的多数网站,其页面都是js语言写的。
在js中,一个字符”0”加一个数字1,js会自动(隐式地)把后者转换为字符串,然后进行拼接。
"0" + 1; // "01"
这其实对你的代码质量(如类型的检验)提出了更高要求,比如你的本意可能是要2个数字相加。
但这段代码会在你毫无知觉的情况下,一直运行下去,导致你可能要在无数代码执行过后,才发现问题。
在Python中,则会报错TypeError错误。
'0' + 1
TypeError: must be str, not int
显然,这说的是一个str,只能和另一个str相加(串联),而不能是一个int。 这个时候你应该用“显式”的类型转换。
所以,当你遇到 TypeError 时,意味着你尝试对不同类型的数据做了它们不支持的操作(比如数字和文字相加)。解决方法通常是:检查涉及的变量类型(用 type()),然后使用 int(), float(), str() 等函数进行显式的类型转换,让它们的类型匹配操作的要求。
在本章中,我们学习了构建程序的基本元素:
核心要点回顾:
=
赋值来创建和更新。type()
查看。int
(整数) 和 float
(浮点数/小数) 用于数值计算。str
(字符串) 用于文本,由引号包围,支持 +
连接和多种方法(如.format()
, f-string)。bool
(布尔型) 只有 True
和 False
,由比较运算符 (==
, !=
, >
, <
, >=
, <=
)产生,用于逻辑判断。None
代表空值。==
和 =
)。and
, or
, not
) 用于组合布尔条件。input()
函数用于获取用户输入,永远返回字符串 (str
)。int()
或 float()
将字符串显式转换为数值类型。snake_case
,有意义)。#
) 用于解释代码,提高可读性。常见错误提示 (本章相关):
NameError
: 尝试使用一个未定义(或拼写错误)的变量名。TypeError
: 尝试对不兼容的数据类型进行操作(如 str
+ int
)。SyntaxError
: 代码不符合Python语法规则(如使用了非法变量名、中文符号、忘记引号等)。ValueError
: 尝试将一个无法解释为目标类型的字符串进行转换(如 int('hello')
)。