深度学习——第03章 Python程序设计语言(3.1 Python语言基础)
无论是在机器学习还是深度学习中,Python已经成为主导性的编程语言。而且,现在许多主流的深度学习框架,例如PyTorch、TensorFlow也都是基于Python。本课程主要是围绕“理论+实战”同时进行,所以本章将重点介绍深度学习中Python的必备知识点。
Python概述
Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。Python具有丰富和强大的库,它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。
为什么人工智能、深度学习会选择Python呢?一方面是因为Python作为一门解释型语言,入门简单、容易上手。另一方面是因为Python的开发效率高,Python有很多库很方便做人工智能,比如Numpy、Scipy做数值计算,Sklearn做机器学习,Matplotlib将数据可视化,等等。总的来说,Python既容易上手,又是功能强大的编程语言。按照《Python学习手册》作者的说法,Python可以支持从航空航天器系统开发到小游戏开发的几乎所有的领域。
其实,人工智能的核心算法的底层还是由C/C++编写的,因为是计算密集型,需要非常精细的优化,还需要GPU、专用硬件之类的接口,这些都只有C/C++能做到。Python实际上是实现API调用的功能,例如所有的深度学习框架PyTorch、TensorFlow等,底层都是由C/C++编写的。由于Python是顶层高级语言,它的缺点就是运行速度慢,但是这丝毫不影响Python的普及。如今,在GPU加速的前提下,Python的运行速度已经很快了。在众多因素影响下,Python毫无疑问成为了人工智能的最主要的编程语言。
!python --version
运行结果:Python 3.8.8
Python语言常用开发环境
- 最常用的:Anaconda的Jupyter Notebook、Pycharm
- 其它:IDLE、Anaconda的Spyter、VScode…
变量、关键字、预定义标识符
变量:可变的量,它的概念和代数中定义的变量基本一致,它由变量名表示。
变量用来存储数据,当程序中需要用到某个变量或者修改某个变量时都可以通过这个名字来操作。
Python中的变量不仅值是可变的,类型也是可变的,因为在Python中变量的使用是极为灵活且方便的,当需要使用一个变量时不需要对其提前进行类型声明。
a = 1
a,type(a)
#运行结果:(1, int)
b = 1.2
b,type(b)
#运行结果:(1.2, float)
变量命名规则(标识符及其命名规则)
命名:Python程序采用“变量”来保存和表示具体的数据值。为了更好地使用变量等程序元素,需要给它们关联一个标识符(名字),这一关联标识符的过程则被称为命名。
命名用于保证程序元素的唯一性。
标识符是变量、函数、类、模块和其他对象的名称,其命名规则为:
Python语言允许采用大小写字母、数字、下画线和汉字等字符及其组合给变量命名,但名字的首字符不能是数字,中间不能出现空格。
如:a2、_a、a_2和student等均为合法变量,但是2a就是一个不合法的变量名;不能有空格以及标点符号,例如a student’s就是一个不合法变量名,因为a和student中有空格,而且出现了不合法的符号单引号;a_int、a_float、str1、_strname、func1为正确的变量名;99var、It’sOK、for(关键字)为错误的变量名。
标识符命名注意事项:
- Python标识符区分大小写。例如,python和Python、Apple和apple都是两个不同的名字。
- 变量名不能使用Python中已有的保留关键字(2.5节)。
- 避免使用Python预定义标识符(2.5节)名作为自定义标识符名。例如:NotImplemented、Ellipsis、int、float、list、str、tuple等。
- 以双下划线开始和结束的名称通常具有特殊的含义。例如,__init__为类的构造函数,一般应避免使用。
- 变量取名时最好有具体的实意,方便其他人读懂程序。如:求和的变量我们最好命名为sum、最大数的变量最好命名为MAX。
a_2, abc, a3 = 1,2,'abc'
a_2, abc, a3
#运行结果:(1, 2, 'abc')
保留关键字
也称保留字、关键字(keywords),指被编程语言内部定义并保留使用的标识符。程序员编写程序时不能定义与保留字相同的标识符。每种程序设计语言都有一套保留字,保留字一般用来构成程序整体框架、表达关键值和具有结构性的复杂语义等。掌握一门编程语言首先要熟记其所对应的保留字,保留字是编程语言的基本单位。
Python对大小写敏感,if是保留字,If就可以是变量名。
查看Python语言关键字:
import keyword
print(keyword.kwlist,len(keyword.kwlist))
运行结果:
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', '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'] 35
预定义标识符
Python语言包含许多预定义内置类、异常、函数等,例如,float、ArithmeticError、print等。
用户应该避免使用Python预定义标识符名作为自定义标识符名。
使用Python的内置函数dir(builtins),可以查看所有内置的异常名、函数名等。
print(dir(__builtins__))
运行结果
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__IPYTHON__', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'display', 'divmod', 'enumerate', 'eval', 'exec', 'execfile', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'runfile', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
help(zip)
运行结果:
Help on class zip in module builtins:
class zip(object)
| zip(*iterables) --> A zip object yielding tuples until an input is exhausted.
|
| >>> list(zip('abcdefg', range(3), range(4)))
| [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]
|
| The zip object yields n-length tuples, where n is the number of iterables
| passed as positional arguments to zip(). The i-th element in every tuple
| comes from the i-th iterable argument to zip(). This continues until the
| shortest argument is exhausted.
|
| Methods defined here:
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __iter__(self, /)
| Implement iter(self).
|
| __next__(self, /)
| Implement next(self).
|
| __reduce__(...)
| Return state information for pickling.
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
算术运算
加法(+)
减法(-)
双目运算符:求两数的差值
单目运算符:某数的负数
除法(/;正斜杠,注意与反斜杠区分)(除数不能为0,否则会报错)
Python中的“/”正斜杠除法运算中,无论除数和被除数为何种类型所得的结果必定是浮点型。如果两个整数正好整除,结果仍是浮点型。
除法想得到整数结果:须使用内置函数int(),或使用整除运算符“//”。
实例:春游乘车问题
问题描述:
某学校要组织春游活动,总人数由程序输入,假设每辆汽车的座位数为30,请计算至少需要多少辆汽车,以及每辆车的人数分配方案。
备注:要求每辆车的人数尽量平均地分布。
解题思路:
被除数、除数、商、余
以总人数101为例,每车30人,共需要4辆车。
其中3辆车乘坐25人,1辆车乘坐26人。
# 春游乘车问题
s = 30 # 每辆车的座位数
np = int(input("师生总人数为:")) # 输入乘车人数
if np % s == 0:
b = np // s
else:
b = np // s + 1
"""计算需要的车辆数b,如果人数除以座位的余数为零,
则车辆数为人数除以座位的商,
否则车辆数为人数除以座位的商。"""
print("共需要", b, "辆汽车,乘车方案为:", sep="")
r = np % b # r为人数除以车辆数的余数,也就是平均后剩余的人数
p = np // b # p为人数除以车辆数的商,也就是每辆车至少平均乘坐的人数
if np % b == 0:
print("每辆车坐", p, "人。", sep="")
else:
print(r, "辆车坐", p + 1, "人;", b - r, "辆车坐", p, "人。", sep="")
输出结果为:
师生总人数为:121
共需要5辆汽车,乘车方案为:
1辆车坐25人;4辆车坐24人。
程序格式框架
Python采用严格的“缩进”来表明程序的格式框架。
a = 2
if a%2 == 1:
print('{}是奇数'.format(a))
else:
print('{}是偶数'.format(a))
输出结果为:
2是偶数
缩进:每行代码开始前的空白区域,用来表示代码之间的包含和层次关系。严格的缩进可以约束程序结构,有利于维护代码结构的可读性。缩进是表达代码间包含和层次关系的唯一手段。
不需要缩进的代码顶行编写,不留空白。
缩进是语法的一部分,缩进不正确程序会运行错误。
缩进可以用Tab键实现,也可以用多个空格。程序内一致即可,一般是4个空格或Tab,建议采用4个空格方式书写代码。
缩进表达了所属关系。
单层缩进:
多层缩进
单层缩进代码属于之前最邻近的一行非缩进代码,多层缩进代码根据缩进关系决定所属范围。
不是所有代码都可以通过缩进包含其他代码,一般来说,判断、循环、函数、类等语法形式能够通过缩进来包含一批代码,进而表达对应的语义。如print()这样简单的语句不表达包含关系,不能使用缩进。
表达式和运算符
表达式
表达式指程序中产生或计算新数据值的一行代码,由操作数和操作符组成。
操作数、运算符和圆括号按一定规则组成表达式。
表达式通过运算后产生运算结果,运算结果的数据类型由操作数和运算共同决定。
表达式是Python语言的基础,表达式类似文章中的名字,可以用空格增加可读性。
表达式即可以非常简单,也可以非常复杂。当表达式包含多个运算符时,运算符的优先级控制各个运算符的计算顺序。
表达式示例:
表达式的书写规则
- 表达式从左到右在同一个基准上书写
例如:数学公式
a
2
+
b
2
a^2+b^2
a2+b2应该写为:
操作数
操作数包括文本常量(没有名称的常数值,如1、“abc”)、变量(如i=123)、类成员变量/函数等,也可以包含子表达式。
运算符:运算符指示对操作数适用什么样的运算。
Python 有如下几种运算符:
- 算术运算符(Arithmetic operator)
- 赋值运算符 (Assignment operator)
- 比较(关系)运算符 (Comparison operator)
- 逻辑运算符 (Logic operator)
- 成员运算符 (Membership operator)
- 身份运算符 (Identity operator)
- 位运算符 (Bitwise operator)
- 海象运算符 (Python 3.8 新出)
Python运算符及其优先级别
运算符用于在表达式中对一个或多个操作数进行计算并返回结果值。接受一个操作数的运算符称作一元运算符,例如,正负号运算符或-。接受两个操作数的运算符被称作二元运算符,例如,算术运算符±*/等。
表达式计算顺序取决于运算符的结合顺序和优先级。
可以使用圆括号“()”强制改变运算顺序。
Python语句
语句是Python程序的过程构造块,用于定义函数、定义类、创建对象、变量赋值、调用函数、控制分支、创建循环等。
通俗一点:语句就是一行一行的代码。
Python语句分为简单语句和复合语句
简单语句:
表达式语句、赋值语句、assert语句、pass空语句、del语句、return语句、yield语句、raise语句、break语句、continue语句、import语句、global语句、nonlocal语句等。
复合语句:
if语句、while语句、for语句、try语句、with语句、函数定义、类定义等。
Python语句的书写规则
-
使用换行符分隔,一般情况下一行一条语句。
-
从第一列开始,前面不能有任何空格,否则会产生语法错误。注意,注释语句可以从任意位置开始;复合语句构造体必须缩进。
-
反斜杠(\)用于一个代码跨越多行的情况
-
分号(;)用于在一行书写多条语句
-
要与Python进行英文交互,要使用半角字符。标识符虽然可以用中文字符,但并不推荐。
复合语句及其缩进书写规则
由多行代码组成的语句称为复合语句。复合语句(条件语句、循环语句、函数定义和类定义,例如if、for、while、def、class等)由头部语句(header line)和构造体语句块(suites)组成。构造体语句块由一条或多条语句组成。复合语句和构造体语句块的缩进书写规则如下:
-
头部语句由相应的关键字(例如,if)开始,构造体语句块则为下一行开始的一行或多行缩进代码。
-
通常缩进是相对头部语句缩进四个空格,也可以是任意空格,但同一构造体代码块的多条语句缩进的空格数必须一致对齐。如果语句不缩进,或缩进不一致,将导致编译错误。
-
如果条件语句、循环语句、函数定义和类定义比较短,可以放在同一行。
for i in range(1,11): print(i, end=' ')
运行结果:
1 2 3 4 5 6 7 8 9 10
注释语句
注释是程序员在代码中加入的一行或多行信息,用来对语句、函数、数据结构或方法等进行说明,提升代码的可读性,或起到标明作者和版权信息、解释代码原理或用途、辅助程序调试的作用。
注释是辅助性文字,会被编译或解释器略去,不被计算或执行,也不会影响程序的执行结果。Python语言有单行和多行两种注释方法:
单行注释:
以符号“#”开始,到行末结束,它可以出现在任何位置。
多行注释:
以三个单引号“‘’'”开头和结尾。
空语句pass
表示一个空的代码块,一般用于语法要求的点位使用。
def abc():
pass
class MyClass:
def __init__(self):
pass
def myfunc(self):
pass
赋值语句
数据必须放入内存才能让计算机程序进行处理。机器语言和汇编语言直接通过内存地址访问这些数据,而高级语言则通过内存单元命名(即变量)来访问这些数据。Python3中,一切皆为对象。对象是某个类(类型)的实例,对象由唯一的id标识。对象可以通过标识符来引用,对象引用即指向具体对象实例的标识符,也称之为“变量”。
变量的声明和赋值
变量的声明和赋值用于把一个变量绑定到某个对象,其语法格式为:
变量名 = 字面量或表达式
变量的声明和赋值示例:
x=0; y=0; z=0 #变量x、y和z均指向int对象0
str1 = "abc" #变量str1指向值为"abc"的str型实例对象
解包赋值
Python支持将系列数据类型解包为对应相同个数的变量。
系列(sequence)数据类型(bytes、bytearray、list、str、tuple)是Python内置的组合数据类型。
系列解包示例:
a,b=1,2 #变量a指向int对象1,变量b指向int对象2
a #输出:1
b #输出:2
输出结果:
2
说明:变量的个数必须与系列的元素个数一致,否则会产生错误。
使用系列解包实现变量交换:
a,b=(1,2) #变量a指向int对象1,变量b指向int对象2
a,b=b,a #两个变量a和b的值进行交换
a #输出:2
b #输出:1
说明:在Python语言中,使用 a,b=b,a 的语句方式,可以优雅地实现两个变量的值交换。
Python程序的输入和输出
- 输入函数input()
input()函数用于从键盘获得用户输入,并以字符串数据类型格式保存。
使用格式:
<变量> = input(“提示信息字符串”)
结果:
用户输入的信息以字符串类型保存在<变量> 中,并输出到屏幕上等待用户输入。
示例:
实例:温度转换
刻画温度的两个体系:摄氏度(Celsius)、华氏度(Fabrenheit)。
不同国家采用不同的体系。
问题描述:
根据输入,识别温度体系和温度,转换为另一个温度体系并按格式输出。
解题思路:
输入:带华氏或摄氏标识的温度值
处理:根据温度标识选择转换算法
输出:带摄氏或华氏标志的温度值
程序实现:
#将带温度体系标记的温度值在摄氏和华氏之间进行转换
t = input('请输入温度值(末尾带温度类型标识C或F):')
if t[-1] in ['c','C']:
C = (eval(t[0:-1])*1.8 + 32)
print('{0}转换为华氏温度为:{1:.2f}F'.format(t,C))
elif t[-1] in ['f','F']:
C = ((eval(t[0:-1]) - 32)/1.8)
print('{0}转换为摄氏温度为:{1:.2f}C'.format(t,C))
else:
print('格式输入错误!')
输出结果:
请输入温度值(末尾带温度类型标识C或F):23F
23F转换为摄氏温度为:-5.00C