Python搬砖之旅(2nd day):基础语法、变量、基础数据类型、运算符、输入输出

在这里插入图片描述

基础语法、变量、基础数据类型、运算符、输入输出

以下我们进入 Python核心编程 的内容,本次主要讲解关于缩进、标识符、表达式、输入输出、整数型、浮点型、字符串型相关的内容。

第一章 Python基础语法

1.1 缩进

缩进的作用是使得程序的结构更加清晰,代码的可读性更好,按照Python的语法规则,处于同一代码块的代码模块应该使用相同的缩进,也就是说,我们应尽量将完成同一功能、处于同一代码块、层级相同的代码写在同一个缩进的代码模块中。在同一层级的代码模块,只有先后之分,没有主从之分;而不同层级的代码则有主从之分。
Python语言默认的缩进单位为4个空格的位置。
代码缩进一般用于函数定义、类定义、分支结构以及循环结构的代码段中。
下面这段代码展示了Python语言中的缩进规则,其中,if…else…是典型的分支程序结构,if 和 else 属于相同的代码模块,所以if 和 else 的缩进是一致的:

age = 18
if age >= 18:
    print("Hello,my friends!")
else:
    print("Hello,kids!")

如果你不能很好把握代码之间应该如何缩进,记住一条"潜规则":在行尾":"之后的代码,往往是需要缩进的
在IDLE、Pycharm等编辑器中,可以通过设置来控制每次缩进的空格数,一般默认设置为"4",这样我们就能使用制表符"Tab"键来快速地使用缩进来调整代码的位置了,在大多数Python的编程环境中,系统会自动将"Tab"制表符转化为4个空格的位置。使用制表符"Tab"的前提是确保使用一致数量的缩进空格,否则会引起系统错误。
缩进的小结:

  • 顺序执行的普通代码,从最左端顶格开始编写,不需要缩进;
  • 一些以关键字开头,冒号结尾的代码段,往往下一行都要缩进;
  • 如果当前代码块的功能执行完毕,需要退回缩进;
  • 如果代码需要分为几个不同层级的模块来执行,那么每个代码模块需要对应不同的缩进。

1.2 注释

Python中常用的注释方式分为单行注释、多行注释。注释是在代码之外的具有帮助性、说明性的文档,程序在执行过程中,并不会执行注释中的内容。注释的快捷键是"CTRL+/"。
单行注释:以"#“开头,可以写在每一行的开头,也可以写在代码之后。
多行注释:以三对单引号’’’…’’’ ,或者三对双引号”""…""",包裹住其中需要注释的文档,一般放在代码段之前,而不放在代码后。
在程序中加入注释,不但可以帮助读者理解代码的功能和作用,以及在一些排错的过程中,可以先注释掉一些代码,观察代码对程序运行的影响,所以说,注释对于程序的编写者和阅读者来说,都是非常重要的,初学者要养成写注释的好习惯。在下面这段文档中,我们使用多行注释和单行注释来帮助读者理解代码将要执行的功能。

# 设置一个变量用来保存对象的年龄
age = 18
"""
以下这段代码的作用是对年龄进行判断,
如果年龄大于等于18岁,打印'你好,我的朋友!';
如果年龄小于18岁,打印'你好,我的孩子!';
"""
if age >= 18:
    print("Hello,my friends!")  #如果年龄大于等于18岁,打印'Hello,my friends!'
else:
    print("Hello,my kids!")     #如果年龄小于18岁,打印'Hello,my kids!'

1.3 标识符

通俗意义上来说,标识符就是程序员给变量、函数、类等取的名字,但是,Python对于标识符的规定较为严格,所以说,名字也是不能乱取的,必须要遵循以下几点原则:

  1. 区分大小写;
    Python是大小写敏感的,也就是说,同样的单词,但是因为大小写的不同,在Python编程环境中,会认为是不同的两个对象,这与其他某些编程语言是不同的。
>>> age = 18   #age是一个变量,给其赋值18
>>> age        #系统能正常地访问age的值
18
>>> Age        #但是系统不能访问Age的对象内容,系统会报"类型错误"
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    Age        #但是系统不能访问Age的对象内容,系统指出错误:Age没有被定义
NameError: name 'Age' is not defined

在上面这段代码中,因为正常地将18这个整数型的数值赋给了age,所以系统在访问age时是正常显示的;但是,Age与age并不是相同的变量,且没有对Age进行任何的赋值操作,所以会导致系统报错。Age只是一个名字,其对应的变量并没有被创建。

  1. 较好的可读性;
    对一个变量、函数或者类来说,我们应尽可能使用英文单词使得其具有可读性,使得读者能够从字面就能理解该变量、函数或者类所代表的含义,而尽量不要去使用诸如"abc",“a1”,“x2"这样意义模糊的变量。
    推荐的变量名:’'name”,“age”,“numbers”
    推荐的函数名:“isOdd”,“count_even_number”
    推荐的类名:“Car”,“Student”

  2. 符合命名规定;
    标识符的第一个字符必须是大小写字母或者下划线,不能是数字或者其他符号,如"$Age"、“1Age”、"&Age"这些都是不合法的标识符,
    标识符的其他的部分由字母、数字和下划线组成,像"_age"、“age1”、"students_age"这样则是合法的标识符。但是,在Python编程语言中,下划线或者双下划线开头的变量或方法具有特殊的含义,这在后面面向对象以及内置的程序方法中会涉及到。如果我们只是命名一个普通的变量、函数或类名,建议以英文字母开头。

  3. 通用的命名方法;
    下划线(蛇形)命名法:英文单词全部小写,中间以下划线"_"连接,常用于函数、方法的命名,
    如 draw_images, get_text等
    小驼峰命名法:除首字母小写外,其余单词的首字母均大写,常用于变量的命名。
    如:pinkPencil, studentClass
    大驼峰命名法:所有单词的首字母均大写,常用于类名的命名。
    如: HtmlText, ConferenceContent等

  4. 不以关键字命名。
    在Python系统中,预先定义了一些常用的字符作为关键字(或称为保留字),这些字符在程序运行中起到关键的语法作用,因而最好不要用来给函数、变量、类进行命名,否则会覆盖其原来的含义,造成程序的混乱。
    关键字在后来的学习中会逐渐积累,所以不需要死记硬背。
    我们可以通过输入import keyword,使用keyword.kwlist来查看所有的关键词

>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
  1. 尽量不以中文字符命名标识符。
    尽管在Python高级的版本中,已经支持使用中文字符做为变量、类或者函数的名称,但是考虑到中文使用的局限性,与程序的泛用性,我们尽量使用英文单词来命名,而不是使用中文字符,这种命名方式对国外的程序阅读者不是很友好。

标识符小作业
以下命名不符合标识符规则的有 ( 多选 ) :
A. list = [1,2,3,4]
B. 01_a = 1
C. name = ‘amy’
D. 年龄 = 18
答案是A、B、D
解析:
1,list是系统保留的关键字,其本身的含义为"列表";
2,数字不能作为标识符的开头;
3,尽量不使用中文作为标识符

第二章 变量

2.1 变量的定义

变量,顾名思义,其代表的值在程序执行过程中会发生变化。
变量的实质是在计算机的内存空间中开辟出的一块区域,我们往往使用变量来保存一些对象的值。
在其他的编程语言中,变量必须在定义后才能使用,而在Python语言中,变量是不需要事先声明的,变量在赋值操作("="为赋值符号)的同时完成变量的声明和定义。

与变量相对的概念是常量,其代表的值在程序执行过程中不会发生变化。Python语言中没有严格地规定常量的表现形式,其通常以变量的形态出现,但是我们在使用程序的过程中,应该遵循开发者的说明,尽量不要去更改常量。在 python 中,使用标识符字母全部大写的方式来识别常量。
无论是变量还是常量,在创建时都会在内存中开辟一块空间,用于保存它的值。

2.2 变量的赋值过程

studentName = "Alice"     #创建一个叫做"Alice"的字符串型的对象,然后将其赋值给studentName这个变量

看一下上面的代码,程序在变量的赋值过程中发生了什么事情呢?
第1步,系统在内存中创建了一个叫做"Alice"的字符串型的对象;
第2步,系统在内存中创建了一个叫做studentName变量,并让该变量指向"Alice"这个字符串型对象。这样,我们在程序中,就可以使用studentName这个变量来代表"Alice"这个字符串型对象了
变量的赋值过程

请同学们观察下面这段代码,说出该段代码的运行结果,然后从A,B,C,D四个选项中选出正确的答案:

# 请说出以下代码的运行结果,然后从A,B,C,D四个选项中选出正确的答案
studentName1 = "Alice"
studentName2 = studentName1
studentName1 = "Jaina"
print(studentName1)
print(studentName2)

A
Alice
Alice
B
Jaina
Jaina
C
Alice
Jaina
D
Jaina
Alice
正确答案是 D
我们来看一下这段代码发生了什么:
首先,系统在内存中创建了"Alice" 这个字符串型的对象,并创建了变量studentName1 指向它;
给studentName1赋值

其次,系统在内存中创建了变量studentName2,并且把studentName1指向的对象传递给它,这样,studentName1和studentName2就同时指向同一个对象,我们这时就认为studentName1和studentName1其实是相等的。
把studentName1的值赋给studentName2
最后,系统在内存中新建了一个字符串型对象"Jaina",并让studentName1这个变量指向它。但此时,studentName2这个变量仍然指向字符串型的对象"Alice"。所以,studentName1对应的值是"Jaina",而studentName2对应的值是"Alice",这样,我们的打印结果就是答案D了。
新建字符串对象并赋值给studentName1

2.3 Python独特的赋值方式

如果有同学学过其他的编程语言,会发现其他的编程语言实现变量的赋值要一个一个依次进行,但是,Python语言是简洁的、高效的,注定Python是不同凡响的。
如果我们要把1这个值同时赋给a,b,c这三个变量,我们可以这么做:

>>> a=b=c=1
>>> a
1
>>> b
1
>>> c
1

赋值操作的过程是从右向左,即先将1赋值给c,再将c的值赋给b,再将b的值赋给a。

如果要在一条语句中将1赋给a,2赋给b,3赋给c,又应该怎么做呢?

>>> a,b,c = 1,2,3
>>> a
1
>>> b
2
>>> c
3

如上图所示,在赋值时,我们可以使用","依次将变量和要赋值的对象分开,这样,值就会一一"映射"到变量上,从而实现变量的快速赋值。
变量赋值小作业
a, b = 6, 8
用一行代码实现 a = 8 , b=6
答案: a,b = b,a
解析,赋值运算是从右向左运行,在赋值运算前,b指向8的值,a指向6的值,那么a,b = b,a则相当于a,b = 8,6,之后的赋值运算,将a指向8的值,将b指向6的值,就实现了a, b 两个变量值互换的运算。

2.4 变量的地址

变量对于程序开发人员来说,就像一座座的小房子,在小房子里装着各种各样的数据对象,要访问这些数据就必须要找到装着数据对象的小房子。那么我们怎么去找到这些小房子呢?聪明的同学们已经猜到了,我们可以通过"地址"去找到房子,进而访问其中的数据对象。在程序中,我们可以使用id()函数来查看变量的地址。
每个变量在内存中都有一个ID地址,我们可以将其理解为变量的地址。当两个不同名称的变量,其地址都是同一个ID的时候,我们认为这两个变量其实是一样的。
下面的代码展示了Python是如何判断两个变量是否是一样的。

>>> studentName1 = "Alice"
>>> studentName2 = "Alice"
>>> id(studentName1)
47961288
>>> id(studentName2)
47961288

我们可以看到,studentName1和studentName2的id地址都是一致的,他们都指向一个相同的字符型数据对象"Alice",所以,studentName1和studentName2是一样的。这就像是一个人有多个外号,但是,其实是同一个人。

我们再来看另外一段代码:

>>> list1 = [1, 2, 3]
>>> list2 = [1, 2, 3]

在这段代码中,list1和list2中的内容都是一致的,他们都是一段包含了1,2,3三个元素的列表,那么问题来了,list1和list2是一样的吗?答案是"否",为什么会这样呢?
我们用id()函数来分析一下

>>> id(list1)
45662408
>>> id(list2)
47817928

从上面的代码我们可以看到,即使list1和list2中的内容都是一致的,但是因为他们指向了不同的内存地址,那么系统也会认为他们也是不一样的。这就像是面貌非常相似的双胞胎,但是,其实是不同的个体。

2.5 小结

  • 在python当中创建变量无需先声明在使用,系统在赋值的同时声明并创建变量
  • 每个变量在使用前都必须赋值,变量被赋值以后才可以使用
  • 赋值号"="的赋值运算符是按照从右往左的计算顺序
  • Python允许同时为多个变量赋值
  • 地址相同的变量,即使变量名不同,系统也认为是一样的
  • 地址不同的变量,及时变量内容一样,系统也认为是不一样的

第三章 基础数据类型

在编程过程中,我们经常会使用各种各样的数据类型,其中有一些基础的数据类型我们会经常使用到,主要包括整数型、浮点型、布尔型、复数性以及字符串型,其中,整数型、浮点型、布尔型、复数性合称为数值类型。
数值类型是一种"不可变"的数据类型,所谓不可变,是指该类型的值一旦不同,那么就变成一个全新的对象。对变量重新赋值,会新建一个数字对象。
变量与数据类型的关系:
变量本身并没有"数据类型"的概念,它只是对于数据对象的"引用"。我们常说的变量的数据类型,其实是指该变量所引用的数据对象的类型。

3.1 整数型

整数型就是我们通常意义上所说的整数,包括0,正整数、负整数,不包括小数点。整数型是我们在编程活动中最经常见到的数据类型,在Python中以"int"来表示整数型。
使用type()可以查看变量的数据类型。

>>> number = 19
>>> type(number)
<class 'int'>

整数型可以用十进制、二进制、八进制、以及十六进制来表示:

  • 十进制 : 不用使用进制符号,正常表示即可。如:19,37等;
  • 二进制 : 使用进制符号0b或0B,如 0b101010 ,0B101010;
  • 八进制 : 使用进制符号0b或0B,如 0o7765,0O7765;
  • 十六进制 :使用进制符号0b或0B,如 0xCF25,0XCF25。

那么,如果将其他进制的值赋值给变量,再将其打印出来,会发生什么事呢?

>>> 0b101010
42
>>> 0B101010
42
>>> 0o7765
4085
>>> 0O7765
4085
>>> 0xcf25
53029
>>> 0XCF25
53029

注意:大写的"O"和0非常相似,我们应注意区分。

知识扩展 : 我们会发现,对应的二进制、八进制、十六进制的值在输出时都默认转换为10进制的值。
那么,有没有办法让其仍然按照二进制、八进制、十六进制这样的形式打印呢?
我们可以借助print函数的格式化打印功能来实现
%d — dec 十进制
%o — oct 八进制
%x — hex 十六进制

>>> num = 29
>>> print("%d"%num)
29
>>> print("%o"%num)
35
>>> print("%x"%(num))
1d

或者是借助 “format” 方法

>>> num = 29
>>> format(num,'b')
'11101'
>>> format(num,'o')
'35'
>>> format(num,'x')
'1d'

我们还可以借助一些函数,这些函数分别是
十进制转换为二进制bin();十进制转换为二进制oct();十进制转换为十六进制hex();

>>> number1 = 0b101010
>>> number1
42
>>> bin(number1)
'0b101010'
>>> number2 = 0o7765
>>> number2
4085
>>> oct(number2)
'0o7765'
>>> number3 = 0XCF25
>>> number3
53029
>>> hex(number3)
'0xcf25'

整数型的强制类型转换
情况一:将字符串转化为整数型数值
在编程实践中,我们还经常使用"强制类型转换"的方法将"字符串型"的数字转化为"整数型"的数字,尤其是在我们使用input()方法输入一个数字字符串的时候,通常,我们会使用str.isdigit()方法来验证数据输入的有效性。

num = input("请输入一个整数:")
print("输入完成后,num的数据类型是",type(num))
if num.isdigit() and "." not in num:
    num = int(num)    # 强制类型转换为int
    print("强制类型转换后,num的数据类型是",type(num))
    print("输入的整数是:",num)
else:
    print("请输入正确的字符,不要输入非数字字符或小数点")

请阅读、复制上面的代码并执行。分别输入"666"、“66.6”、“A666”,观察执行结果。
需要注意的是,强制类型转换的时候,如果字符串带有非数字字符或者小数点,系统都会提示错误。

情况二:将浮点型数值转化为整数型数值
在编程实践中,有时需要使用"强制类型转换"的方法将"浮点型"的数字转化为"整数型"的数字。
需要注意的是,“浮点型"的数字转化为"整数型"的数字并不是进行"四舍五入”,而是只取其数字的整数部分。

>>> int(3.2)
3
>>> int(5.5)
5
>>> int(7.9)
7

扩展内容
整数型数值的内存分配
在Python程序被启动的时候,为了避免数值型对象被重复调用,程序本身会在其初始化的时候就建立一个范围从[-5, 256]的一个"小整数对象池"。在这个对象池中,数字是按顺序排列的。在内存中,整数型数值对象的长度是32位,所以,我们可以看到,连续的整数之间的地址间隔是32。

>>> id(1)
493514208
>>> id(2)
493514240
>>> id(3)
493514272
>>> id(-6)
45887600
>>> id(257)
45887568

从上面的代码我们可以看出,连续的数字处于连续的内存地址段,而在[-5,256]范围之外的数字,其内存地址与其存在较大差异。
因为小整数对象池的存在,我们发现,即使是我们创建了不同的变量,但是,只要变量中的值在[-5,256]的范围内,那么,其实这些变量还是指向同一个内存地址。

>>> num1 = -5
>>> num2 = -5
>>> id(num1)
493514016
>>> id(num2)
493514016
>>> num1 = -6
>>> num2 = -6
>>> id(num1)
45887536
>>> id(num2)
45887696

通过上面的代码,我们可以看到,我们在程序中创建了num1和num2两个变量,其值都为-5。
因为-5 在[-5, 256]的范围内,所以num1和num2两个变量指向了同一个内存地址;
但是,之后重新对num1和num2两个变量进行赋值为-6,因为-6不在[-5, 256]的范围内,所以num1和num2两个变量指向了不同的内存地址。
小整数对象池的作用是节省内存开销,加快程序运行速度。变量的值在[-5, 256]范围内的整数,其指向的数据内存地址是一样的。

整数缓冲区
除了小整数对象池之外,Python 还有整数缓冲区的概念,也就是说刚被删除或抛弃的整数,
在内存中并不会被立刻回收,而是先在后台缓冲一段时间,等待下一次的可能调用;如果在限制时间内,有其他的变量使用该整数,则该整数会继续保留在内存中,否则会被系统回收。(该整数必须是[-5,256]范围之外的整数)

num1 = 1000  # 给变量num1赋一个-5到256范围之外的值
print("num1的地址", id(num1))    # 显示num1的内存地址
num1 = 1002  # 给num1赋一个新值,原来的1000被抛弃
num2 = 1000  # 让num2指向num1原来的值1000
print("num1的地址", id(num1))    # 显示num1的内存地址
print("num2的地址", id(num2))    # 显示num2的内存地址

程序运行的结果:

num1的地址 45074160
num1的地址 45772848
num2的地址 45074160

我们可以看到,变量num1原来的值为1000,指向内存地址"45074160";当num1被赋予一个新值的时候,通常原来的值所在的内存空间会在一段时间后被系统回收。但是,由于,变量num2又立即被赋予了1000这个值,所以num2指向了num1原来指向的内存地址,1000这个数值所在的内存空间得以继续保留。

3.2 浮点型

与整数型相对,浮点型就是带小数点的数字,由整数部分和小数部分组成,比如我们常见的"π",在程序中,我们经常将其作为一个常量表示出来。

>>> PI = 3.1415926
>>> print(PI)
3.1415926

对于很大或很小的浮点数,一般用科学计数法表示,把10用e替代,如1.23x10^9就是1.23e9,或者
12.3e8,0.000012可以写成1.2e-5,等等

浮点型的数值之间进行计算并不是完全精准的,可能会遇到四舍五入的情况,比如5/3会得到1.6666666666666667

>>> 5/3
1.6666666666666667

如果一个整数与一个浮点数相加、相减、相乘、相除,结果都是一个浮点数。

>>> a,b = 1,2.0
>>> a+b
3.0
>>> a-b
-1.0
>>> a*b
2.0
>>> a/b
0.5

问题:5.4 - 2 的结果是什么?
哈哈,我已经猜到你们要说是 3.4了, 可是,在程序里真的是这样的吗?

>>> 5.4 - 2
3.4000000000000004

是不是很奇怪?为什么会在3.4之后多出来一个小尾巴?
其实,不光是Python程序,在其他的程序里也会出现这个问题。学过《大学计算机基础》的同学们应该都容易理解,在计算机系统中,所有的数值都是先转化为二进制数值,再进行运算的。
整数部分不会出现尾数,是因为任意一个十进制的整数数,都能转换为对应的二进制数;但是,任意一个十进制的小数,就没有这么幸运了。
我们来看下0.4对应的二进制数是多少?
使用乘二取整法,得到的是一个无限循环的小数:0.011001100110011…B,这就意味着误差,所以,再将二进制的数值转换回十进制之后,我们就会发现其身后带着的一长串的小尾巴。
那么,有没有办法解决这个问题呢?有的,我们可以使用decimal模块中的Decimal类来解决这个问题。

>>> from decimal import Decimal
>>> print(Decimal('5.4')-Decimal('2'))
3.4
>>> print(Decimal(5.4)-Decimal(2))
3.400000000000000355271367880

我们可以看到打印的结果是3.4,原来的结果中的“小尾巴”就没有了。需要注意的,我们需要使用数字型字符串作为参数进行计算,否则还会像之前那样产生很多的尾数。

与整数型相同,浮点型的数值也可以使用强制类型转换的方法:
情况一:将字符串型数值转化为浮点型数值
与整数型的情况基本一样,但是需要注意注意的是字符串中可以不带小数点,会强制转换为带小数点的形式。

>>> float("3")
3.0
>>> float("3.4")
3.4

情况二:将整数型数值转化为浮点型数值。
整数型数值转换为浮点型数值,直接在其后面加上小数点和0即可

>>> float(3)
3.0

3.3 布尔型

在计算机中,我们经常需要判断"正确"与"错误"的情况。布尔型是一种表示逻辑的简单类型,该类型的元素只有"True"和"False"两个,分别表示逻辑上的"真"和"假"。
常用的布尔型数值有:and 与运算 , or 或运算, not 非运算
A and B 与运算 : 只有两个变量同时为"True"时,其运算结果才能为"True",否则运算结果为"False";
A or B 或运算 : 两个变量其中之一为"True"时,其运算结果为"True",否则运算结果为"False";
not A 非运算 : 当变量的值为"True"时,其运算结果为"False";当变量的值为"False"时,其运算结果为"True"。

>>> A,B = True,True
>>> A and B
True
>>> A or B
True
>>> A,B = True,False
>>> A and B
False
>>> A or B
True
>>> A,B = False,False
>>> A and B
False
>>> A or B
False
>>> C = True
>>> not C
False
>>> C = False
>>> not C
True

注意: 在Python程序中,有几种情况需要值得我们引起注意:
1,对于数值型的数据对象,0代表False,而其他非0的数值代表True;
2,对于字符串、列表、集合、字典等数据对象,空(None)带表False,非空代表True。
3,True的默认值为1
我们使用bool()函数来判断该数据对象是否为真

>>> bool(0)  # 数值型0代表False
False
>>> bool(0.0)  # 数值型0.0也代表False
False
>>> bool(None) # "None"就是空,指没有值或没有数据对象,代表False
False

>>> bool(1)  # 数值型非0代表True
True
>>> bool(-10)  # 数值型非0代表True,即使是负数也一样
True

>>> bool("")   # 非数值型0代表False,比如空字符串
False
>>> bool([])   # 非数值型0代表False,比如空列表
>False
>>> bool({})   # 非数值型0代表False,比如空字典
False

>>> bool('yes')  # 非空字符串表示True
True
>>> bool([1, 2, 3])  # 非空列表表示True
True
>>> bool({1:"first", 2:"second", 3:"third"})  # 非空字典表示True
True

小结:
在Python程序中,数值0 和 0.0,数据对象None(空)代表False,其他代表True。

在Python程序中,布尔型的值常用语分支结构的程序语句或者作为while循环语句的判断条件。

3.4 字符串型

在Python中,用一对单引号或者一对双引号包裹起来的字符集合称之为字符串,其对应的数据类型为str。

>>> str1 = "Python"
>>> str1
'Python'
>>> str1 = 'python'
>>> str1
'python'
>>> type(str1)
<class 'str'>

还有一种用三对单引号或三对双引号包裹起来的字符集合,其中的字符可以由多行组成,我们在讲注释的时候已经介绍过这种形式了,在这里就不做过多的介绍。
字符串中的字符可以包括大小写字母、数字、中文字符、特殊符号,以及一些转义符。
转义符是指一些具有特殊含义的字符,用于实现特定的功能。注意:转义符只占据一个字符的位置。
常见的转移字符请参考https://www.runoob.com/python3/python3-string.html这篇网页的内容。
在这里插入图片描述
字符串这一部分的内容比较多,我会在单独的一章的中来详细阐述如何处理字符串。

第四章 运算符

4.1 算术运算符

算术运算符指用来实现算术运算的特殊符号,比如常见的加法"+",减法"-",乘法"*",“除法/“等等,需要注意的是,算术运算符是有优先级的,一般来说乘法”*”,“除法/“的优先级要大于加法”+”,减法"-"。

另外需要注意的是:

  • 整数与浮点数的运算,最后的结果都是浮点数
  • 除法运算,即使被除数与除数都是整数,其结果也是浮点数

除了加减乘除之外,还有其他一些常用的算术运算符:

** 幂运算,x ** y 表示取得x的y次方,如 5**2 得到25。幂运算的优先级最高。

// 向下取整运算 , 返回商的整数部分,如 5//2 得到2,5.0//2得到2.0,5//-2 得到-3
同学们一定非常好奇,为什么5//-2 会得到-3。
为了解释这个原理,我们先来看看 5 // 2的过程:
首先,我们计算 5 / 2,得到结果 2.5,然后向下取整,得到2,所以5//2 返回整数值 2;
同理,我们计算 5 / -2 ,得到结果 -2.5,然后向下取整,得到 -3 (因为-3 小于 -2),所以,5//-2 返回整数值 -3。

% 向下取余数运算 ,如 5 % 3 得到 2,10 % -3 得到 -2,-10 % 3得到2。
正整数的取余数过程同学们应该没有问题,但是对负数的取余数会存在疑问。
首先,我们来看下正数取余数的过程。
5 // 3 得到商为 1,然后用 5 - ( 1 * 3 ) 得到2,OK,没有问题;
然后是负数取余的过程
10 // -3 得到商 -4,然后用10 - (-3 *-4) = 10 -12 = -2;
最后,同理,-10 // 3 得到商-4,然后用 -10 - (3 * -4)=-10 + 12 = 2;
所以,你知道Python中取余数的算法了吗?
第一步:用被除数除以除数,向下取整得到商;
第二步:用被除数减去商与除数的乘积,就得到余数。

小练习:请写出20 // 3, 20 // -3,20 % 3, 20 % -3的值
答案:20 // 3的结果是6;20 // -3的结果是-7;
20 % 3的结果是2, 20 % -3的结果是-1

扩展知识:
如果想要同时的到商和余数,可以使用divmod方法,该方法会同时返回两个数,第一个数是商,第二个是余数。比如我们用divmod计算一下14除以3的结果。

>>> divmod(14,3)
(4, 2)

可以看到14除以3,商数为4,余数为2。divmod方法的应用范围并不多,同学们只需要稍作了解即可。

算术运算符小练习
由用户输入 a,b的值(a,b均为整数) 。当 a 与 b 都不为 0 时,如果 a > b 则输出 a 与 b 的商 ;如果 a > b 则输出 a 与 b 的乘积。
答案:

a = int(input("请先输入a的值:"))
b = int(input("请再输入b的值:"))
if a != 0 and b != 0 :
    if a > b:
        print(a // b)
    else:
        print(a * b)

算术运算符小结

  1. 算术运算中,幂运算的优先级最高
  2. 取余运算"%"、 向下取整运算"//“和乘法”*","除法/"的优先级一样,所以有时需要借助小括号()来确定运算的优先级,有()优先计算小括号中的内容

4.2 比较运算符

比较运算符常用来比较两个数字的大小,结果返回True或者False。
需要注意的是,除了可以使用纯数字进行比较之外,也可以进行变量、表达式之间的比较。
比较运算符的优先级小于算术运算符的优先级。
常见的比较运算符有:
“A == B” : 比较变量A的值是否与B的值相等,相等则返回True,不等则返回False;
“A != B” : 比较变量A的值是否与B的值不相等,不相等则返回True,相等则返回False;
“A > B” : 比较变量A的值是否大于B的值,大于则返回True,否则返回False;
“A < B” : 比较变量A的值是否小于B的值,小于则返回True,否则返回False;
“A >= B” : 比较变量A的值是否大于或等于B的值,是则返回True,否则返回False;
“A <= B” : 比较变量A的值是否小于或等于B的值,是则返回True,否则返回False;

举例:

>>> 33 > 55
False
>>> a,b = 33,55
>>> a > b
False
>>> a+b > a-b
True

思考:2 == 2.0的结果是什么?
答案是True。因为整数和浮点数进行比较时,会将整数化为浮点数的形式进行比较。
但是,数字型的值与字符型的值之间不能直接相互比较。

思考: a, b, c = 1,2,3,那么a<b<c的运行结果是?
很多同学都会回答True,对的,那么你们知道这其中的逻辑关系吗?
划重点:a<b<c 等价于 a<b and b<c
所以,a<b<c 等价于 1<2 and 2<3,返回的结果当然是True了。

扩展知识:字符串之间的比较
字符与字符之间也可以进行比较,但是,字符之间的比较其实是比较的他们所对应的ASCII码。
学过《大学计算机基础》的同学们应该记得,ASCII码是一个7位的编码,用来代表大小写英文字母、数字、以及其他特殊符号的一共128个字符的码表。
ASCII码表
从上面的ASCII码表中我们就可以发现,大小写字符其实在ASCII码表中其实是有“编号”的,比如"a"对应的编号为97,而"A"对应的编号为65,这样就为我们比较字符串的大小提供了可行性。我们可以使用ord()函数来获取大小写字母在ASCII码表中对应的值

>>> ord('a')
97
>>> ord('A')
65
>>> a > A
>>> 'a' > 'A'
True

从上面的例子可以看出,字符串的比较,其实是比较他们在ASCII码表中所代表的值。
如果遇到多字符的字符串,或者首字母相同的字符串又该如何比较呢?
字符串比较的规则是:
首先比较首字符,首字符码值大的比较大;
如果首字母相同,则比较第二个字母,以此类推。
例如:

>>> 'abcde' > 'Abcde'
True
>>> 'abcde' > 'abcdE'
True

比较运算符小练习
说出‘ax’<’xa’ 的计算结果?
答案:True。
解析:两个字符串进行比较,先进行首字符的比较,若首字符相同再依次比较下一个字符。
本题中‘ax’的首字符是’a’,’xa’ 的首字符是’x’。'a’对应ASCII码表值为97,‘x’对应ASCII码表值为120,
所以’a’<‘x’,所以‘ax’<’xa’ 。

小结:

  • 数值型不能直接与字符型比较
  • Python3 中不支持 <> 号,应使用 != 符号
  • == 与 != 符号 不能分开写成, “= =” 以及 "! ="是错误的写法
  • 字符串与字符串之间比较的是 ASCII码表中对应的值,并且从首字母开始逐个比较
  • 连续比较,如:a>b>c 等价于 a>b and b>c

4.3 赋值运算符

常见的赋值运算符是"=" , 其作用是将一个数据对象赋值给变量。
除了常规的赋值运算外,还有一些复合赋值运算。
a ** = b 等价于 a = a ** b
a %= b 等价于 a = a % b
a //= b 等价于 a = a // b
a *= b 等价于 a = a * b
a /= b 等价于 a = a / b
a += b 等价于 a = a + b
a -= b 等价于 a = a - b

4.4 逻辑运算符

在Python程序中,只允许将 and, or ,not三种运算符用于逻辑运算。
A and B:逻辑与运算,如果A的值为False,则返回False,否则返回B的值;
A or B :逻辑或运算,如果A的值为True,则返回A的值,否则返回B的值;
not A :逻辑非运算,如果A的值为True,则返回False;如果A的值为False,则返回True。
这部分的运算规则,可参考布尔型数据类型的内容。

注意:在计算机中,一般使用数字1代表True,用数字0代表False

>>> 1 == True
True
>>> 0 == False
True

也就是说,1和True是等价的,而0和False也是等价的;
在程序判断中,还存在另外一条规则:
“默认状态下,0代表False,而非0代表True;空代表False,而非空代表True”。

我们来看一下这段代码的运行结果:

>>> print(10 and 20)
20
>>> print(10 or 20)
10

为什么10 and 20的运算结果是20 ,而10 or 20 的运算结果是10呢?这就涉及到逻辑运算中的规则:“短路原则”,即在结果已经确定的情况下,程序不会再去计算后续的逻辑变量。
先来看下 10 and 20 的计算过程:
首先,程序取得10这个数值 ,因为10是一个非0的整数,系统认为其代表"True";
其次,程序需要进行"and"与的运算。在与运算中,只有其中一方为True,其结果是并不能确定的,还需要取到下一个值才能判定最终的结果 。
最后,取得20这个值,因为20也是一个非0的整数,系统认为其代表"True",所以程序会把最后代表True的20打印出来。

接下来,看下 10 or 20 的计算过程:
首先,程序取得10这个数值 ,因为10是一个非0的整数,系统认为其代表"True";
其次,程序需要进行"or"或的运算。在或运算中,只要其中有一方为True,其结果就已经可以确定为True,程序就不需要取到下一个值才能判定最终的结果 。所以,在确定结果的同时,程序不会再计算后续的逻辑变量。
最后,程序会把最后代表True的10打印出来。

逻辑运算小练习
下面这些代码的运行结果是什么?

print(0 and 10)
print(10 and 0)
print(0 or 10)
print(10 or 0)

答案:

>>> print(0 and 10)
0
>>> print(10 and 0)
0
>>> print(0 or 10)
10
>>> print(10 or 0)
10

解析:
0 and 10 ,0代表False,and逻辑与运算只要其中一个值为False,其结果就一定为False,0等价于False,所以程序会返回0。
10 and 0 , 10 为非0整数,代表True,但是and逻辑与运算在只有1个值为True的情况下不能确定,程序会继续向后取到0 。因为0代表False,所以之后的值无论如何,表达式的值一定为False。而0等价于False,所以将0打印了出来。
0 or 10,or逻辑或运算需要两个值同时为False,才能确定结果为False。第一个值是0,代表False,但是运算的结果并不能确定,所以继续向后取值。10是一个非0的整数,系统认为其代表"True",就不需要继续计算后续的数值,程序会把代表True的10打印出来。
10 or 0,or逻辑或运算只要其中一个值为True,其结果就一定为True,10是一个非0的整数,系统认为其代表"True",就不需要继续计算后续的数值,程序会把代表True的10打印出来。

逻辑运算符小结:

  • 非0的整数和True等价,0和False等价;
  • 非空(Not Null)代表True,空(Null)代表False;
  • 短路原则会在结果已经确定的情况下,返回最后访问的值,而不会进行后续的计算。

4.5 位运算符

位运算符只针对二进制的位运算。
& : 按位与
| : 按位或
^ : 按位异或
我相信学过《大学计算机基础》的同学对此并不陌生。
运算口诀:
& : 按位与 —— 有0 为0,没0为1;
| : 按位或 —— 有1 为1,没1为0;
^ : 按位异或 —— 相同为0,不同为1;
先上案例:

>>> a,b = 60,13
>>> a & b
12
>>> a | b
61
>>> a ^ b
49

其实计算过程就三步:

  1. 将十进制的变量转化为二进制的值;
  2. 对二进制的值按位进行计算;
  3. 把二进制的计算结果再转回到十进制。

60对应的二进制数为’00111100’
13对应的二进制数为’00001101’,注意左边不足的位数用0补齐。
‘00111100’ & ‘00001101’ 的结果是’00001100’,对应十进制数 12;
‘00111100’ | ‘00001101’ 的结果是’00111101’,对应十进制数 61;
‘00111100’ ^ ‘00001101’ 的结果是’00110001’,对应十进制数 49;
好吧,其实就是这么简单。

4.6 成员运算符

in 成员属于某个数据集合,返回True,否则返回False;
not in 成员不属于某个数据集合,返回True,否则返回False。
在Python数据结构中,有一些数据的“容器”,比如说列表、元组、字典、集合,当需要判断某个元素是否属于该“容器”时,成员运算符就能够帮助我们很好地解决这个问题。

>>> 'a' in ['a', 'b', 'c']
True
>>> 'd' in ['a', 'b', 'c']
False
>>> 'a' not in ['a', 'b', 'c']
False
>>> 'd' not in ['a', 'b', 'c']
True

我们再来看一段代码:

a = [3]
b = 3
alist = [1, 2, 3, 4, 5]
print(a in alist)
print(b in alist)

a in alist的结果是False,b in alist的结果是True。
因为a的数据类型是一个列表,而alist中的元素并不包括该列表;
b的数据类型是一个整数,而alist中的元素中包含该整数。
那么同学们猜一猜,如果把alist改成 alist = [1, 2, [3], 4, 5],即在列表中嵌套一个列表,
那么a in alist的结果会是什么?

成员运算符小练习
判断字符串 “Amy” 是否在列表[“bob”,“tony”,“Lisa”,“Steven”,“Angela”] 里面:
如果在,则输出 ‘Amy和大家在一起,好开心!’
否则,输出 ’ Amy没有和大家在一起 … 好难过!’
答案:

name = "Amy"
studentList = ["bob","tony","Lisa","Steven","Angela"]
if name in studentList:
    print('Amy和大家在一起,好开心!')
else:
    print('Amy没有和大家在一起...好难过!')

4.7 身份运算符

身份运算符是Python独具特色的语法。
is : 判断两个对象的内存地址是否一致,是则返回True,否则返回False。
not is : 判断两个对象的内存地址是否不一致,是则返回True,否则返回False。
还记得我们之前讲过的id()函数吗?用于获取变量的地址。
如果两个变量指向同一个地址,我们就认为这两个变量是相同的,就像一个人叫不同的名字;
而如果两个变量内容一致,但是指向了不同的地址,我们就认为这两个变量是不相同的,就像双胞胎长得很像但其实是两个人。
例如:

>>> a = "Alice"
>>> b = "Alice"
>>> id(a)
46453960
>>> id(b)
46453960
>>> a is b
True
>>> a == b
True
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> id(a)
46591368
>>> id(b)
46650760
>>> a is b
False
>>> a == b
True

注意:is 与 == 的区别

  • is 用于判断两个变量的引用是否为同一个内存地址 ( 可使用 id() 查看 )
  • == 用于判断两个变量的值是否相等

身份运算符小结:
只看变量的id地址就能知道到底是一个人还是双胞胎了。值相同的不一定是同一个人,地址相同才可以。

4.8 三目运算符

语法格式:[True_statements] if [expression] else [False_statements]
三目运算符其实是简化的if … else … 判断语句。
三目运算的程序结构等价于:
if [expression] :
[True_statements]
else:
[False_statements]
这是我们将要学到的分支结构的语法,翻译为中文就是:
“如果条件[expression] 的判断结果为True,就执行[True_statements],否则执行[False_statements]”
案例:

a, b = 1, 2
#实现:当 a+b>3  执行 a+b ,否则执行 b-a
print(a+b if a+b>3 else b-a)

结果是1 。 因为a+b的结果是3,所以a+b>3的条件不成立,判断为False,那么就会执行else之后的语句,
b-a 就相当于2-1,结果为1。

三目运算符小练习1:
用户输入 a,b ,当 a 与 b 都不为 0 时则输出 a 与 b 的乘积 ;否则输出 a 与 b 的和。
答案:

a = int(input("请先输入a的值:"))
b = int(input("请再输入b的值:"))
print(a * b if a != 0 and b != 0 else a + b)

三目运算符小练习2:
用户输入 a,b ,使用三目运算符输出 a,b 中较大的数

a = int(input("请先输入a的值:"))
b = int(input("请再输入b的值:"))
print(a if a >= b else b)

4.9 运算符的优先级

一般而言,幂运算 ** 优先级最高,其次是乘法、除法、取余、取整运算,然后是加法、减法,再次是 赋值运算,最后是逻辑运算。
除了以上运算符之外,还有其他一些运算符,但这里只介绍最常用的几种运算符。如果对运算符有兴趣,同学们可以参考这个网页:
https://www.runoob.com/python/python-operators.html
在这里插入图片描述
运算符优先级小练习

#以下程序如果输入 666 执行那个语句 ? 为什么 ?
temp = input('请输入666: ')
if temp == 'Yes' or 'yes':
    print('if 执行了! ')
else:
    print('else 执行了! ')

我猜很多同学会认为结果是’else 执行了! ',但是其实结果是,“if 执行了!”

请输入666666
if 执行了! 

想不到吧!那么为什么会这样?
我们注意到,"==" 比较运算符的优先级高于 ‘or’ 逻辑或运算的优先级,所以上面那句判断语句的条件,其真实的效果是:
temp == ‘Yes’ or ‘yes’ 等价于 (temp == ‘Yes’) or (‘yes’ )
temp == ‘Yes’吗?明显不是。因为temp代表字符串’666’,‘666’ == ‘Yes’的结果明显是False。
但是, or 右边是非空字符串’yes’ , 非空代表True,所以,不论你输入什么样的字符,逻辑或判断的结果都一定是"True",也就一定会打印出结果’if 执行了! ‘。
如果我们想让程序必须输入’Yes’ 或者 ‘yes’ 才能打印结果’if 执行了! ',我们就需要对判断条件做如下的修改:

temp = input(' 请输入666: ')
if temp == 'Yes' or temp == 'yes' :
    print('if 执行了! ')
else:
    print('else 执行了! ')

运算符优先级小结:

  • 算术运算 > 位运算 > 比较运算 > 赋值运算 > 身份运算 > 成员运算 > 逻辑运算
  • 在不确定优先级的情况下,使用小括号使得优先级运算更为明确。

第五章 输入与输出

5.1 input输入函数

input() 是Python的内置函数,用来获取用户输入,其返回值为字符串类型。当用户未输入时,程序会阻塞进程,停止就向下执行,并等待用户输入,直到用户输入完成再继续执行。

age = input("请输入你的年龄:")
print("你的年龄是:",age)
print("age的数据类型是:",type(age))

请阅读并执行以上的代码(假设输入年龄为18),说一说代码的结果是什么?

请输入你的年龄:18
你的年龄是: 18
age的数据类型是: <class 'str'>

从结果中我们可以看到,input函数返回的是一个字符串类型的对象,然后将这个字符串对象赋值给了age这个变量,所以age的数据类型是str。那么问题来了,如果我们想使用输入的数字进行数学运算该怎么办呢?

num1 = input("请输入昨天的营业额:")
num2 = input("请输入今天的营业额:")
print("",num1+num2)

上面这段代码有什么问题?
问题1:num1和num2是字符串类型,不能用于数字运算。
问题2:字符串和字符串使用"+"运算符会将两个字符串拼接在一起。

请输入昨天的营业额:180.55
请输入今天的营业额:260.74
昨天和今天的营业额合计为: 180.55260.74

哈哈,结果是不是很奇怪?那我们应该怎么去修改呢?

num1 = float(input("请输入昨天的营业额:"))
num2 = float(input("请输入今天的营业额:"))
print("昨天和今天的营业额合计为:",num1+num2)
请输入昨天的营业额:180.55
请输入今天的营业额:260.74
昨天和今天的营业额合计为: 441.29

在这里,我们使用了强制类型转换的方法,将字符串类型的"180.55"和"260.74"转换为了浮点型的180.55和260.74,并分别赋值给num1和num2,这样num1和num2就能进行数值运算,得到我们想要的结果了。
需要注意的是,强制类型转换必须是字符串中的内容全部为数字才可以。
提示:使用str.isdigit() 判断字符串是否全部为数字组成

input 输入函数小练习1:
用户输入 id_card
判断 id_card 是否为全数字
是,则打印输出 id_card
否,则打印输出 ‘id_card 格式错误’

id_card = input("请输入你的id_card:")
if id_card.isdigit():
    print(id_card)
else:
    print('id_card 格式错误')

input 输入函数小练习2:
输入年龄
当年龄大于18,则输出”你好呀,小靓仔”;
否则输出”你好呀!小朋友”

while(True):
    age = input("请输入你的年龄:")
    if age.isdigit():
        age = int(age)
        if age >= 18:
            print("你好呀,小靓仔!")
            break
        else:
            print("你好呀!小朋友!")
            break
    else:
        print("请重新输入正确的数字。")
        continue

5.2 print输出函数

print输出函数用于打印输出,语法为:print(self, *args, sep=’ ‘, end=’\n’, file=None)
参数中sep表示各个值之间的分割符,默认为空格;end表示结尾处的符号,默认为换行符。

>>> num1,num2,num3,num4 = 1,2,3,4
>>> print(num1,num2,num3,num4,sep="+")
1+2+3+4
>>> print(num1,num2,num3,num4,sep="+",end='=')
1+2+3+4=
>>> print(num1,num2,num3,num4,sep="",end='')
1234

观察以上的代码片段,并考虑为什么输出结果是这样?

print输出函数小作业1:
num1,num2,num3,num4 = 1,2,3,4
使用print语句把整个等式打印出来,即打印出"1+2+3+4=10"的效果
参考答案:

num1,num2,num3,num4 = 1,2,3,4
print(num1,num2,num3,num4,sep="+",end='=')
print(num1+num2+num3+num4)

print输出函数小作业2:
print(‘12’)
print('3
4’)
使用一个 print 语句实现上面两个 print() 语句输出的效果
参考答案:

print('1*2','3*4',sep='\n')

print语句的格式化输出:
方法一:使用格式化字符,需要注意的是,格式化字符需要与变量的类型保持一致。
%s:对应字符串类型
%d:对应整数型类型
%.2f:对应浮点数类型,".2"表示保留两位小数

>>> name,age,money = "Ross",20,200000
>>> print("%s虽然只有%d岁,但是她已经赚到了%.2f元的钱了。"%(name,age,money))
Ross虽然只有20岁,但是她已经赚到了200000.00元的钱了。

方法二:使用format函数,需要注意的是,format函数中打印的顺序默认为顺序执行,但是打印顺序可以人为控制。
更多详细信息请参考:https://www.runoob.com/python/att-string-format.html

>>> name,age,money = "Ross",20,200000
print("{}虽然只有{}岁,但是她已经赚到了{:.2f}元的钱了。".format(name,age,money))
Ross虽然只有20岁,但是她已经赚到了200000.00元的钱了。

5.3 小结

input输入函数的特征:

  1. 阻塞:程序会等待用户输入,输入完成后继续执行
  2. 返回值为字符串:input函数会返回一个字符串类型的值。

print函数的特征:

  1. 输出值之间使用sep参数作为分隔符
  2. 输出后使用end参数作为行的末尾。
  3. 可以使用格式化符号指定打印格式
  • 13
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清弦墨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值