1.1、什么是编程语言
其实,程序指的就是一系列指令,用来告诉计算机做什么,而编写程序的关键在于,我们需要用计算机可以理解的语言来提供这些指令。
为了有效避开所有影响给计算机传递指令的因素,计算机科学家设计了一些符号,这些符号各有其含义,且之间无二义性,通常称它们为编程语言。编程语言中的每个结构,都有固定的使用格式(称为语法)以及精确的含义(称为语义)。换句话说,编程语言指定了成套的规则,用来编写计算机可以理解的指令。习惯上,我们将这一条条指令称为计算机代码,而用编程语言来编写算法的过程称为编码。
本教程要讲解的 Python] 就是一种编程语言,除此之外,你肯定也听说过其他一些编程语言,如 C、C++,Java、Ruby 等。至今,计算机科学家已经开发了成百上千种编程语言,且随着时间演变,这些编程语言又产生了多个不同的版本。但无论是哪个编程语言,也无论有多少个版本,虽然它们在细节上可能有所不同,无疑它们都有着固定的、无二义性的语法和语义。
以上提到的编程语言,都是高级计算机语言,设计它们的目的是为了方便程序员理解和使用。但严格来说,计算机硬件只能理解一种非常低级的编程语言,称为机器语言。
1.2、编译型语言和解释型语言的区别
我们编写的源代码是人类语言,我们自己能够轻松理解;但是对于计算机硬件(CPU),源代码就是天书,根本无法执行,计算机只能识别某些特定的二进制指令,在程序真正运行之前必须将源代码转换成二进制指令。所谓的二进制指令,也就是机器码,是 CPU 能够识别的硬件层面的“代码”。
然而,究竟在什么时候将源代码转换成二进制指令呢?不同的编程语言有不同的规定:
-
有的编程语言要求必须提前将所有源代码一次性转换成二进制指令,也就是生成一个可执行程序(Windows 下的 .exe),比如C语言、C++、Go、Pascal(Delphi)、汇编等,这种编程语言称为编译型语言,使用的转换工具称为编译器。
-
有的编程语言可以一边执行一边转换,需要哪些源代码就转换哪些源代码,不会生成可执行程序,比如 Python、JavaScript、PHP、Shell、MATLAB等,这种编程语言称为解释型语言,使用的转换工具称为解释器。
1、简单理解,编译器就是一个“翻译工具”,类似于将中文翻译成英文、将英文翻译成俄文。但是,翻译源代码是一个复杂的过程,大致包括词法分析、语法分析、语义分析、性能优化、生成可执行文件等几个步骤
2、Java和 C#是一种比较奇葩的存在,它们是半编译半解释型的语言,源代码需要先转换成一种中间文件(字节码文件),然后再将中间文件拿到虚拟机中执行。Java 引领了这种风潮,它的初衷是在跨平台的同时兼顾执行效率;C# 是后来的跟随者,但是 C# 一直止步于 Windows 平台,在其它平台鲜有作为。
图 1 编译型语言和解释型语言的执行流程
那么,编译型语言和解释型语言各有什么特点呢?它们之间有什么区别?
对于编译型语言,开发完成以后需要将所有的源代码都转换成可执行程序,比如 Windows 下的.exe
文件,可执行程序里面包含的就是机器码。只要我们拥有可执行程序,就可以随时运行,不用再重新编译了,也就是“一次编译,无限次运行”。在运行的时候,我们只需要编译生成的可执行程序,不再需要源代码和编译器了,所以说编译型语言可以脱离开发环境运行。编译型语言一般是不能跨平台的,也就是不能在不同的操作系统之间随意切换。
对于解释型语言,每次执行程序都需要一边转换一边执行,用到哪些源代码就将哪些源代码转换成机器码,用不到的不进行任何处理。每次执行程序时可能使用不同的功能,这个时候需要转换的源代码也不一样。因为每次执行程序都需要重新转换源代码,所以解释型语言的执行效率天生就低于编译型语言,甚至存在数量级的差距。计算机的一些底层功能,或者关键算法,一般都使用 C/C++ 实现,只有在应用层面(比如网站开发、批处理、小工具等)才会使用解释型语言。
在运行解释型语言的时候,我们始终都需要源代码和解释器,所以说它无法脱离开发环境。
当我们说“下载一个程序(软件)”时,不同类型的语言有不同的含义:
-
对于编译型语言,我们下载到的是可执行文件,源代码被作者保留,所以编译型语言的程序一般是闭源的。
-
对于解释型语言,我们下载到的是所有的源代码,因为作者不给源代码就没法运行,所以解释型语言的程序一般是开源的。
相比于编译型语言,解释型语言几乎都能跨平台,“一次编写,到处运行”是真是存在的,而且比比皆是。那么,为什么解释型语言就能跨平台呢?这一切都要归功于解释器!
我们所说的跨平台,是指源代码跨平台,而不是解释器跨平台。解释器用来将源代码转换成机器码,它就是一个可执行程序,是绝对不能跨平台的。解释型语言之所以能够跨平台,是因为有了解释器这个中间层。在不同的平台下,解释器会将相同的源代码转换成不同的机器码,解释器帮助我们屏蔽了不同平台之间的差异。
Python 属于典型的解释型语言,所以运行 Python 程序需要解释器的支持,只要你在不同的平台安装了不同的解释器,你的代码就可以随时运行,不用担心任何兼容性问题,真正的“一次编写,到处运行”。Python 几乎支持所有常见的平台,比如 Linux、Windows、Mac OS、Android、FreeBSD、Solaris、PocketPC 等,你所写的 Python 代码无需修改就能在这些平台上正确运行。也就是说,Python 的可移植性是很强的。
1.3、Python介绍
Python 英文原意为“蟒蛇”,直到 1989 年荷兰人 Guido van Rossum (简称 Guido)发明了一种面向对象的解释型编程语言,并将其命名为 Python,才赋予了它表示一门编程语言的含义。
Python 语言是在 ABC 教学语言的基础上发展来的;遗憾的是,ABC 语言虽然非常强大,但却没有普及应用,Guido 认为是它不开放导致的。基于这个考虑,Guido 在开发 Python 时,不仅为其添加了很多 ABC 没有的功能,还为其设计了各种丰富而强大的库,利用这些 Python 库,程序员可以把使用其它语言制作的各种模块(尤其是C语言和 C++)很轻松地联结在一起,因此 Python 又常被称为“胶水”语言。
Python的语言优势有以下几个点:
-
简单易学
-
跨平台
-
丰富强大的库
-
极高的开发效率
-
应用领域广泛
-
扩展性强
1.4、Python环境安装
1.4.1、解释器的类型
'''
(1)Cpython(官方推荐)
把python转化成c语言能识别的二进制码
(2)Jpython
把python转化成java语言能识别的二进制码
(3)其他语言解释器
把python转化成其他语言能识别的二进制码
(4)PyPy
将所有代码一次性编译成二进制码,加快执行效率(模仿编译型语言的一款python解释器)
'''
1.4.2、Cpython解释器的版本
'''
python 2.x 版本,官方在 2020 年停止支持,原码不规范,重复较多
python 3.x 版本,功能更加强大且修复了很多bug,原码清晰,简单
'''
1.4.3、下载安装Python解释器
Python 安装包下载地址:https://www.python.org/downloads/
安装完成以后,打开 Windows 的命令行程序(命令提示符),在窗口中输入python
命令(注意字母p
是小写的),如果出现 Python 的版本信息,并看到命令提示符>>>
,就说明安装成功了,如下图所示。
请尽量勾选
Add Python 3.8 to PATH
,这样可以将 Python 命令工具所在目录添加到系统 Path 环境变量中,以后开发程序或者运行 Python 命令会非常方便。
1.5、Python的第一个程序
python python文件名
二、基础语法
2.1、变量
2.1.1、python的标识符规范
简单地理解,标识符就是一个名字,就好像我们每个人都有属于自己的名字,它的主要作用就是作为变量、函数、类、模块以及其他对象的名称。Python中标识符的命名不是随意的,而是要遵守一定的命令规则
'''
1、标识符是由字符(A~Z 和 a~z)、下划线和数字组成,但第一个字符不能是数字。
2、标识符不能和 Python 中的保留字相同。有关保留字,后续章节会详细介绍。
3、Python中的标识符中,不能包含空格、@、% 以及 $ 等特殊字符。
4、在 Python 中,标识符中的字母是严格区分大小写
5、Python 语言中,以下划线开头的标识符有特殊含义
6、Python 允许使用汉字作为标识符(不推荐)
'''
标识符的命名,除了要遵守以上这几条规则外,不同场景中的标识符,其名称也有一定的规范可循,例如:
'''
- 当标识符用作模块名时,应尽量短小,并且全部使用小写字母,可以使用下划线分割多个字母,例如 game_mian、game_register 等。
- 当标识符用作包的名称时,应尽量短小,也全部使用小写字母,不推荐使用下划线,例如 com.mr、com.mr.book 等。
- 当标识符用作类名时,应采用单词首字母大写的形式。例如,定义一个图书类,可以命名为 Book。
- 模块内部的类名,可以采用 "下划线+首字母大写" 的形式,如 _Book;
- 函数名、类中的属性名和方法名,应全部使用小写字母,多个单词之间可以用下划线分割;
- 常量命名应全部使用大写字母,单词之间可以用下划线分割;
'''
2.1.2、python的关键字
and | as | assert | break | class | continue |
---|---|---|---|---|---|
def | del | elif | else | except | finally |
for | from | False | global | if | import |
in | is | lambda | nonlocal | not | None |
or | pass | raise | return | try | True |
while | with | yield |
2.1.3、变量
变量是一段有名字的连续存储空间。我们通过定义变量来申请并命名这样的存储空间,并通过变量的名字来使用这段存储空间。在编程语言中,将数据放入变量的过程叫做赋值(Assignment)。Python 使用等号=
作为赋值运算符,具体格式为:
变量名 = 任意类型的值(存储数据)
例如:
x = 10
y = "hi,yuan"
z = True
# 变量的值可以随时被修改,只要重新赋值即可 而且,你也不用关心数据的类型
x = "hello world"
思考:
x = 10
x = 20
y = x
y = 30
print(x)
print(y)
2.2、语句分隔符和缩进规则
在C、Java等语言的语法中规定,必须以分号作为语句结束的标识。Python也支持分号,同样用于一条语句的结束标识。但在Python中分号的作用已经不像C、Java中那么重要了,Python中的分号可以省略,主要通过换行来识别语句的结束。
和其它程序设计语言(如
注意,Python 中实现对代码的缩进,可以使用空格或者 Tab 键实现。但无论是手动敲空格,还是使用 Tab 键,通常情况下都是采用 4 个空格长度作为一个缩进量(默认情况下,一个 Tab 键就表示 4 个空格)。
Python 的设计哲学是优雅、明确、简单
2.3、注释
注释(Comments)用来向用户提示或解释某些代码的作用和功能,它可以出现在代码中的任何位置。
一般情况下,合理的代码注释应该占源代码的 1/3 左右。Python 支持两种类型的注释,分别是单行注释和多行注释。
# Python的单行注释
'''
Python的多行注释
这是注释代码,不被解释器执行的内容
'''
注意事项:
(1) Python 多行注释不支持嵌套
(2) 不管是多行注释还是单行注释,当注释符作为字符串的一部分出现时,就不能再将它们视为注释标记,而应该看做正常代码的一部分,例如:
print('''Hello,World!''')
print("""http://c.biancheng.net/cplus/""")
print("#是单行注释的开始")
2.4、输入输出函数
print("hi,yuan") # 输入函数
input(">>>") # 输入函数
2.5、Python编码规范(PEP 8)
Python 采用 PEP 8 作为编码规范,其中 PEP 是 Python Enhancement Proposal(Python 增强建议书)的缩写,8 代表的是 Python 代码的样式指南。下面仅给大家列出 PEP 8 中初学者应严格遵守的一些编码规则:
1、每个 import 语句只导入一个模块,尽量避免一次导入多个模块,例如:
#推荐
import os
import sys
#不推荐
import os,sys
关于 import 的含义和用法会在后续介绍,这里不必深究。
2、不要在行尾添加分号,也不要用分号将两条命令放在同一行
3、建议每行不超过 80 个字符,如果超过,建议使用小括号将多行内容隐式的连接起来,而不推荐使用反斜杠 \ 进行连接。例如,如果一个字符串文本无法实现一行完全显示,则可以使用小括号将其分开显示,代码如下:
#推荐
s=("C语言中文网是中国领先的C语言程序设计专业网站,"
"提供C语言入门经典教程、C语言编译器、C语言函数手册等。")
#不推荐
s="C语言中文网是中国领先的C语言程序设计专业网站,\
提供C语言入门经典教程、C语言编译器、C语言函数手册等。"
4、使用必要的空行可以增加代码的可读性,通常在顶级定义(如函数或类的定义)之间空两行,而方法定义之间空一行,另外在用于分隔某些功能的位置也可以空一行。
5、通常情况下,在运算符两侧、函数参数之间以及逗号两侧,都建议使用空格进行分隔。
三、基本数据类型
3.1、整型
整数就是没有小数部分的数字,Python 中的整数包括正整数、0 和负整数。有些强类型的编程语言会提供多种整数类型,每种类型的长度都不同,能容纳的整数的大小也不同,开发者要根据实际数字的大小选用不同的类型。例如C语言提供了 short、int、long、long long 四种类型的整数,它们的长度依次递增,初学者在选择整数类型时往往比较迷惑,有时候还会导致数值溢出。而 Python 则不同,它的整数不分类型,或者说它只有一种类型的整数。Python 整数的取值范围是无限的,不管多大或者多小的数字,Python 都能轻松处理。
x = 10
print(type(x)) # <class 'int'>
x = 100000000000000000000000000000000000000000000000000
print(type(x))
print(x)
进制
# 十六进制
print(0x11)
print(0x111)
# 二进制
print(0b101)
print(0B101)
# 八进制
print(0o12)
print(0o23)
# 十进制转换为二进制
print(bin(3))
# 十进制转换为十六进制
print(hex(19))
# 十进制转换为八进制
print(oct(10))
3.2、浮点类型
在编程语言中,小数通常以浮点数的形式存储。
Python中的小数有两种书写形式:
(1) 十进制形式
这种就是我们平时看到的小数形式,例如 34.6、346.0、0.346。书写小数时必须包含一个小数点,否则会被 Python 当作整数处理。
(2)指数形式
Python 小数的指数形式的写法为:aEn 或 aen
指数形式的小数举例:
2.1E5 = 2.1×105,其中 2.1 是尾数,5 是指数。
3.7E-2 = 3.7×10-2,其中 3.7 是尾数,-2 是指数。
0.5E7 = 0.5×107,其中 0.5 是尾数,7 是指数。
注意,只要写成指数形式就是小数,即使它的最终值看起来像一个整数。例如 14E3 等价于 14000,但 14E3 是一个小数。Python 只有一种小数类型,就是 float。
f1 = 3.14
print(f1)
print(type(f1)) # <class 'float'>
f2 =0.000000000000000000000000000000003
print(f2)
print(type(f2))
f3 = 3.141592612345678987654321
print(f3)
print(type(f3))
f4 = 12e4
print(f4)
print(type(f4))
3.3、布尔类型
Python提供了 bool 类型来表示真(对)或假(错),比如常见的5 > 3
比较算式,这个是正确的,在程序世界里称之为真(对),Python 使用 True 来代表;再比如4 > 20
比较算式,这个是错误的,在程序世界里称之为假(错),Python 使用 False 来代表。
print(4 == 2) # False
print(5 > 1) # True
name = "yuan"
print(name == "alex") # False
print(1=="1") # False
True 相当于整数值 1,False 相当于整数值 0。
3.4、字符串类型
字符串是由零个或多个字符组成的有限序列。字符串的内容可以包含字母、标点、特殊符号、中文、日文等全世界的所有字符。
s1 = "hi yuan"
print(s1)
s2 = ""
print(s2)
s3 = "苑是最好的老师!"
print(s3)
Python 字符串中的双引号和单引号没有任何区别
3.4.1、转义符
转义字符 | 说明 |
---|---|
\n | 换行符,将光标位置移到下一行开头。 |
\r | 回车符,将光标位置移到本行开头。 |
\t | 水平制表符,也即 Tab 键,一般相当于四个空格。 |
\a | 蜂鸣器响铃。注意不是喇叭发声,现在的计算机很多都不带蜂鸣器了,所以响铃不一定有效。 |
\b | 退格(Backspace),将光标位置移到前一列。 |
\ | 反斜线 |
' | 单引号 |
" | 双引号 |
\ | 在字符串行尾的续行符,即一行未完,转到下一行继续写。 |
s1 = "hi yuan\noldboyedu"
print(s1)
s2 = 'I\'m yuan'
print(s2)
s3 = "D:\\nythonProject\\nenv\\Scripts\\python.exe"
print(s3)
3.4.2、长字符串
Python 长字符串由三个双引号"""
或者三个单引号'''
包围,语法格式如下:
'''
Python 长字符
'''
"""
Python 长字符
"""
在长字符串中放置单引号或者双引号不会导致解析错误。如果长字符串没有赋值给任何变量,那么这个长字符串就不会起到任何作用,和一段普通的文本无异,相当于被注释掉了。
注意,此时 Python 解释器并不会忽略长字符串,也会按照语法解析,只是长字符串起不到实际作用而已。当程序中有大段文本内容需要定义成字符串时,优先推荐使用长字符串形式,因为这种形式非常强大,可以在字符串中放置任何内容,包括单引号和双引号。
3.4.3、格式化输出
方式1:
之前讲到过 print() 函数的用法,这只是最简单最初级的形式,print() 还有很多高级的玩法,比如格式化输出,这就是本节要讲解的内容。print() 函数使用以%
开头的转换说明符对各种类型的数据进行格式化输出,具体请看下表。
转换说明符 | 解释 |
---|---|
%d、%i | 转换为带符号的十进制整数 |
%o | 转换为带符号的八进制整数 |
%x、%X | 转换为带符号的十六进制整数 |
%e | 转化为科学计数法表示的浮点数(e 小写) |
%E | 转化为科学计数法表示的浮点数(E 大写) |
%f、%F | 转化为十进制浮点数 |
%g | 智能选择使用 %f 或 %e 格式 |
%G | 智能选择使用 %F 或 %E 格式 |
%c | 格式化字符及其 ASCII 码 |
%r | 使用 repr() 函数将表达式转换为字符串 |
%s | 使用 str() 函数将表达式转换为字符串 |
name = "yuan"
age = 23
print("My name is %s; My age is %d"%(name,age))
在 print() 函数中,由引号包围的是格式化字符串,它相当于一个字符串模板,可以放置一些转换说明符(占位符)。本例的格式化字符串中包含一个%s
和%d
说明符,它最终会被后面的name和age 变量的值所替代。中间的%
是一个分隔符,它前面是格式化字符串,后面是要输出的表达式。
方式2:
相对基本格式化输出采用‘%’的方法,format()功能更强大,该函数把字符串当成一个模板,通过传入的参数进行格式化,并且使用大括号‘{}’作为特殊字符代替‘%’
(1)不带编号,即“{}”
(2)带数字编号,可调换顺序,即“{1}”、“{2}”
(3)带关键字,即“{name}”、“{age}”
name = "yuan"
age = 23
print("My name is {}; My age is {}".format(name,age))
print("My name is {1}; My age is {0}".format(name,age))
print("My name is {n}; My age is {a}".format(n=name,a=age))
3.4.4、字符串内置方法
大小写处理
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
capitalize | 首字母大写,其余小写 | ‘lk with psr'.capitalize() | ‘Lk with psr' |
upper | 全部大写 | ‘lk with psr'.upper() | ‘LK WITH PSR' |
lower | 全部小写 | ‘lk with psr'.lower() | ‘lk with psr' |
swapcase() | 大小写互换 | ‘Lk with Psr'.swapcase() | ‘lK WITH pSR' |
.title() | 首字母大写 | ‘lk with psr'.title() | ‘Lk With Psr' |
判断字符串中的字符类型
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
startswith(‘a',[start,end]) | 是否以a开头 | ‘a lk'.startswith(‘a') | True |
endswith(‘a') | 是否以a结尾 | ‘lk'.endswith(‘a') | False |
isalnum() | 是否全为字母或数字 | ‘123asd'.isalnum() | True |
isalpha() | 是否全字母 | ‘lk12'.isalpha() | True |
isdigit() | 是否全数字 | ‘123'.isdigit() | True |
islower() | 是否全小写 | ‘lk'.islower() | True |
isupper() | 是否全大写 | ‘lk'.isupper() | False |
istitle() | 判断首字母是否为大写 | ‘Lk'.istitle() | True |
isspace() | 判断字符是否为空格 | ' '.isspace() | True |
字符串替换
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
replace(‘old',‘new') | 替换old为new | 'hello world'.replace(‘world',‘python') | hello python |
replace(‘old',‘new',次数) | 替换指定次数的old为new | 'hello world'.replace(‘l',‘p',2) | heppo world |
去空格
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
strip() | 去两边空格 | ' h e-l lo '.strip() | 可以想象 |
lstrip() | 去左边空格 | ' h e-l lo '.lstrip() | 可以想象 |
rstrip() | 去右边空格 | ' h e-l lo '.rstrip() | 可以想象 |
用特定符连接单个字符
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
.join() | -连接 | ‘-'.join([‘a', ‘b', ‘c']) | a-b-c |
用字符串中的特定符分割字符串
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
split() | 默认按空格分隔 | ' h e-l lo ' .split() | [‘h', ‘e-l', ‘lo'] |
split(‘指定字符') | 按指定字符分割字符串为数组 | ' h e-l lo ' .split('-') | [' h e', 'l lo '] |
搜索
函数 | 作用 | 示例 | 输出 |
---|---|---|---|
find() | 搜索指定字符串,没有返回-1 | ‘lk la'.find(‘lk') | 0 |
index() | 同上,但是找不到会报错 | ‘lk la'.index(‘lk') | 0 |
rfind() | 从右边开始查找 | ‘lk la'.rfind(‘lk') | 0 |
count() | 统计指定的字符串出现的次数 | ‘lklklk'.count(‘lk') | 3 |
四、进阶数据类型
4.1、序列介绍
所谓序列,指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通过每个值所在位置的编号(称为索引)访问它们。
为了更形象的认识序列,可以将它看做是一家旅店,那么店中的每个房间就如同序列存储数据的一个个内存空间,每个房间所特有的房间号就相当于索引值。也就是说,通过房间号(索引)我们可以找到这家旅店(序列)中的每个房间(内存空间)。
4.1.1 、序列索引
序列中,每个元素都有属于自己的编号(索引)。从起始元素开始,索引值从 0 开始递增,如图 1 所示。
除此之外,Python 还支持索引值是负数,此类索引是从右向左计数,换句话说,从最后一个元素开始计数,从索引值 -1 开始,如图 2 所示。
4.1.2、序列切片
切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列。序列实现切片操作的语法格式如下:
序列类型对象[start : end : step]
其中,各个参数的含义分别是:
start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片;
end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度;
step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略。
4.1.3、序列相加与相乘
Python 中,支持两种类型相同的序列使用“+”运算符做相加操作,它会将两个序列进行连接,但不会去除重复的元素。使用数字 n 乘以一个序列会生成新的序列,其内容为原来序列被重复 n 次的结果
print("welcome"+" to"+" oldboyedu")
print("*"*10)
print("*"*30+"welcome to oldboyedu"+"*"*30)
4.1.4、检查元素是否包含在序列中
Python 中,可以使用 in 关键字检查某元素是否为序列的成员。
print("yuan" in "hi,yuan")
4.2、列表类型
在实际开发中,经常需要将一组(不只一个)数据存储起来,以便后边的代码使用。说到这里,一些读者可能听说过数组(Array),它就可以把多个数据挨个存储到一起,通过数组下标可以访问数组中的每个元素。
4.2.1、列表的创建
从形式上看,列表会将所有元素都放在一对中括号[ ]
里面,相邻元素之间用逗号,
分隔,如下所示:
[element1, element2, element3, ..., elementn]
列表中的元素个数没有限制,只要是 Python 支持的数据类型就可以。从内容上看,列表可以存储整数、小数、字符串、列表、元组等任何类型的数据,并且同一个列表中元素的类型也可以不同。
4.2.2、访问列表元素
列表是 Python 序列的一种,我们可以使用索引(Index)访问列表中的某个元素(得到的是一个元素的值),也可以使用切片访问列表中的一组元素(得到的是一个新的子列表)。
使用索引访问列表元素的格式为:
listname[i]
其中,listname
表示列表名字,i 表示索引值。列表的索引可以是正数,也可以是负数。
使用切片访问列表元素的格式为:
listname[start : end : step]
其中,listname
表示列表名字,start 表示起始索引,end 表示结束索引,step 表示步长。
4.2.3、列表的增删改查之增
添加方法: append、extend、insert
<1>append() 方法用于在列表的末尾追加元素,该方法的语法格式如下:
listname.append(obj)
其中,listname
表示要添加元素的列表;obj 表示到添加到列表末尾的数据,它可以是单个元素,也可以是列表、元组等。
<2>extend() 和 append() 的不同之处在于:extend() 不会把列表或者元祖视为一个整体,而是把它们包含的元素逐个添加到列表中。
extend() 方法的语法格式如下:
listname.extend(obj)
其中,listname
指的是要添加元素的列表;obj 表示到添加到列表末尾的数据,它可以是单个元素,也可以是列表、元组等,但不能是单个的数字。
<3> append() 和 extend() 方法只能在列表末尾插入元素,如果希望在列表中间某个位置插入元素,那么可以使用 insert() 方法。
insert() 的语法格式如下:
listname.insert(index , obj)
其中,index 表示指定位置的索引值。insert() 会将 obj 插入到 listname
列表第 index 个元素的位置。
当插入列表或者元祖时,insert() 也会将它们视为一个整体,作为一个元素插入到列表中,这一点和 append() 是一样的。
4.2.4、列表的增删改查之删
在Python列表中删除元素主要分为以下 3 种场景:
-
根据目标元素所在位置的索引进行删除,可以使用 del 关键字或者 pop() 方法;
-
根据元素本身的值进行删除,可使用列表(list类型)提供的 remove() 方法;
-
将列表中所有元素全部删除,可使用列表(list类型)提供的 clear() 方法。
<1>del
是 Python 中的关键字,专门用来执行删除操作,它不仅可以删除整个列表,还可以删除列表中的某些元素。我们已经在《
del
可以删除列表中的单个元素,格式为:
del listname[index]
其中,listname
表示列表名称,index 表示元素的索引值。
del
也可以删除中间一段连续的元素,格式为:
del listname[start : end]
其中,start 表示起始索引,end 表示结束索引。del
会删除从索引 start 到 end 之间的元素,不包括 end 位置的元素。
<2> Python pop() 方法用来删除列表中指定索引处的元素,具体格式如下:
listname.pop(index)
其中,listname
表示列表名称,index 表示索引值。如果不写 index 参数,默认会删除列表中的最后一个元素.
<3>除了del
关键字,Python 还提供了 remove() 方法,该方法会根据元素本身的值来进行删除操作。需要注意的是,remove() 方法只会删除第一个和指定值相同的元素,而且必须保证该元素是存在的,否则会引发ValueError
错误。
4.2.4、列表的增删改查之改
Python提供了两种修改列表(list)元素的方法,你可以每次修改单个元素,也可以每次修改一组元素(多个)。修改单个元素非常简单,直接对元素赋值即可.
修改一组元素,Python 支持通过切片语法给一组元素赋值。在进行这种操作时,如果不指定步长(step 参数),Python 就不要求新赋值的元素个数与原来的元素个数相同;这意味,该操作既可以为列表添加元素,也可以为列表删除元素。
4.2.5、列表的增删改查之查
Python 列表(list)提供了 index() 和 count() 方法,它们都可以用来查找元素。
4.3、元组类型
元组(tuple)是 Python中另一个重要的序列结构,和列表类似,元组也是由一系列按特定顺序排序的元素组成。
元组和列表(list)的不同之处在于:
-
列表的元素是可以更改的,包括修改元素值,删除和插入元素,所以列表是可变序列;
-
而元组一旦被创建,它的元素就不可更改了,所以元组是不可变序列。元组也可以看做是不可变的列表,通常情况下,元组用于保存无需修改的内容。
从形式上看,元组的所有元素都放在一对小括号( )
中,相邻元素之间用逗号,
分隔,如下所示:
(element1, element2, ... , elementn)
其中 element1~elementn
表示元组中的各个元素,个数没有限制,只要是 Python 支持的数据类型就可以。
需要注意的一点是,当创建的元组中只有一个字符串类型的元素时,该元素后面必须要加一个逗号
,
,否则 Python 解释器会将它视为字符串。
4.4、字典类型
Python字典(dict
)是一种无序的、可变的序列,它的元素以“键值对(key-value)”的形式存储。相对地,列表(list)和元组(tuple)都是有序的序列,它们的元素在底层是挨着存放的。
字典类型是 Python 中唯一的映射类型。“映射”是数学中的术语,简单理解,它指的是元素之间相互对应的关系,即通过一个元素,可以唯一找到另一个元素。如图 1 所示。
字典中,习惯将各元素对应的索引称为键(key),各个键对应的元素称为值(value),键及其关联的值称为“键值对”。
字典类型很像学生时代常用的新华字典。我们知道,通过新华字典中的音节表,可以快速找到想要查找的汉字。其中,字典里的音节表就相当于字典类型中的键,而键对应的汉字则相当于值。
主要特征 | 解释 |
---|---|
通过键而不是通过索引来读取元素 | 字典类型有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。 |
字典是任意数据类型的无序集合 | 和列表、元组不同,通常会将索引值 0 对应的元素称为第一个元素,而字典中的元素是无序的。 |
字典是可变的,并且可以任意嵌套 | 字典可以在原处增长或者缩短(无需生成一个副本),并且它支持任意深度的嵌套,即字典存储的值也可以是列表或其它的字典。 |
字典中的键必须唯一 | 字典中,不支持同一个键出现多次,否则只会保留最后一个键值对。 |
字典中的键必须不可变 | 字典中每个键值对的键是不可变的,只能使用数字、字符串或者元组,不能使用列表。 |
4.4.1、创建字典
使用 { } 创建字典,由于字典中每个元素都包含两部分,分别是键(key)和值(value),因此在创建字典时,键和值之间使用冒号:
分隔,相邻元素之间使用逗号,
分隔,所有元素放在大括号{ }
中。
使用{ }
创建字典的语法格式如下:
dictname = {'key':'value1', 'key2':'value2', ..., 'keyn':valuen}
其中
dictname
表示字典变量名,keyn : valuen
表示各个元素的键值对。需要注意的是,同一字典中的各个键必须唯一,不能重复。
4.4.2、访问字典
列表和元组是通过下标来访问元素的,而字典不同,它通过键来访问对应的值。因为字典中的元素是无序的,每个元素的位置都不固定,所以字典也不能像列表和元组那样,采用切片的方式一次性访问多个元素。
Python 访问字典元素的具体格式为:
dictname[key]
其中,dictname
表示字典变量的名字,key 表示键名。注意,键必须是存在的,否则会抛出异常。
除了上面这种方式外,Python 更推荐使用 dict
类型提供的 get() 方法来获取指定键对应的值。当指定的键不存在时,get() 方法不会抛出异常。
get() 方法的语法格式为:
dictname.get(key[,default])
其中,dictname
表示字典变量的名字;key 表示指定的键;default 用于指定要查询的键不存在时,此方法返回的默认值,如果不手动指定,会返回 None。
4.4.3、字典的基本操作
由于字典属于可变序列,所以我们可以任意操作字典中的键值对(key-value)。Python 中,常见的字典操作有以下几种:
-
向现有字典中添加新的键值对。
-
修改现有字典中的键值对。
-
从现有字典中删除指定的键值对。
-
判断现有字典中是否存在指定的键值对。
1、Python字典添加键值对
为字典添加新的键值对很简单,直接给不存在的 key 赋值即可,具体语法格式如下:
dictname[key] = value
对各个部分的说明:
-
dictname
表示字典名称。 -
key 表示新的键。
-
value 表示新的值,只要是 Python 支持的数据类型都可以。
2、Python字典修改键值对
Python 字典中键(key)的名字不能被修改,我们只能修改值(value)。
字典中各元素的键必须是唯一的,因此,如果新添加元素的键与已存在元素的键相同,那么键所对应的值就会被新的值替换掉,以此达到修改元素值的目的。
3、Python字典删除键值对
如果要删除字典中的键值对,还是可以使用 del
语句。
4、判断字典中是否存在指定键值对
如果要判断字典中是否存在指定键值对,首先应判断字典中是否有对应的键。判断字典是否包含指定键值对的键,可以使用 in 或 not in 运算符。
四、运算符
4.1、算数运算符
运算符 | 说明 | 实例 | 结果 |
---|---|---|---|
+ | 加 | 12.45 + 15 | 27.45 |
- | 减 | 4.56 - 0.26 | 4.3 |
* | 乘 | 5 * 3.6 | 18.0 |
/ | 除法(和数学中的规则一样) | 7 / 2 | 3.5 |
// | 整除(只保留商的整数部分) | 7 // 2 | 3 |
% | 取余,即返回除法的余数 | 7 % 2 | 1 |
** | 幂运算/次方运算,即返回 x 的 y 次方 | 2 ** 4 | 16,即 24 |
4.2、赋值运算符
运算符 | 说 明 | 用法举例 | 等价形式 |
---|---|---|---|
= | 最基本的赋值运算 | x = y | x = y |
+= | 加赋值 | x += y | x = x + y |
-= | 减赋值 | x -= y | x = x - y |
*= | 乘赋值 | x *= y | x = x * y |
/= | 除赋值 | x /= y | x = x / y |
%= | 取余数赋值 | x %= y | x = x % y |
**= | 幂赋值 | x **= y | x = x ** y |
//= | 取整数赋值 | x //= y | x = x // y |
&= | 按位与赋值 | x &= y | x = x & y |
|= | 按位或赋值 | x |= y | x = x | y |
^= | 按位异或赋值 | x ^= y | x = x ^ y |
<<= | 左移赋值 | x <<= y | x = x << y,这里的 y 指的是左移的位数 |
>>= | 右移赋值 | x >>= y | x = x >> y,这里的 y 指的是右移的位数 |
4.3、比较运算符
比较运算符 | 说明 |
---|---|
> | 大于,如果> 前面的值大于后面的值,则返回 True,否则返回 False。 |
< | 小于,如果< 前面的值小于后面的值,则返回 True,否则返回 False。 |
== | 等于,如果== 两边的值相等,则返回 True,否则返回 False。 |
>= | 大于等于(等价于数学中的 ≥),如果>= 前面的值大于或者等于后面的值,则返回 True,否则返回 False。 |
<= | 小于等于(等价于数学中的 ≤),如果<= 前面的值小于或者等于后面的值,则返回 True,否则返回 False。 |
!= | 不等于(等价于数学中的 ≠),如果!= 两边的值不相等,则返回 True,否则返回 False。 |
is | 判断两个变量所引用的对象是否相同,如果相同则返回 True,否则返回 False。 |
is not | 判断两个变量所引用的对象是否不相同,如果不相同则返回 True,否则返回 False。 |
4.4、逻辑运算符
逻辑运算符 | 含义 | 基本格式 | 说明 |
---|---|---|---|
and | 逻辑与运算,等价于数学中的“且” | a and b | 当 a 和 b 两个表达式都为真时,a and b 的结果才为真,否则为假。 |
or | 逻辑或运算,等价于数学中的“或” | a or b | 当 a 和 b 两个表达式都为假时,a or b 的结果才是假,否则为真。 |
not | 逻辑非运算,等价于数学中的“非” | not a | 如果 a 为真,那么 not a 的结果为假;如果 a 为假,那么 not a 的结果为真。相当于对 a 取反。 |
五、流程控制语句
和其它编程语言一样,按照执行流程划分,Python 程序也可分为 3 大结构,即顺序结构、选择(分支)结构和循环结构:
-
Python 顺序结构就是让程序按照从头到尾的顺序依次执行每一条 Python 代码,不重复执行任何代码,也不跳过任何代码。
-
Python 选择结构也称分支结构,就是让程序“拐弯”,有选择性的执行代码;换句话说,可以跳过没用的代码,只执行有用的代码。
-
Python 循环结构就是不断地重复执行同一段代码。
5.1、分支语句
Python 中的 if else 语句可以细分为三种形式,分别是 if
语句、if else
语句和if elif else
语句
5.1.1、if
语句
语法格式:
if 表达式:
代码块
5.1.2、if-else
语句
语法格式:
if 表达式:
代码块 1
else:
代码块 2
5.1.3、if-elif-else
语句
语法格式:
if 表达式 1:
代码块 1
elif 表达式 2:
代码块 2
elif 表达式 3:
代码块 3
...# 其它elif语句
else:
代码块 n
对语法格式的说明:
1、“表达式”可以是一个单一的值或者变量,也可以是由运算符组成的复杂语句,形式不限,只要它能得到一个值就行。不管“表达式”的结果是什么类型,if else 都能判断它是否成立(真或者假)。
2、“代码块”由:与具由相同缩进标识的若干条语句组成。
5.2、循环语句
5.2.1、while 循环
Python 中,while 循环和 if 条件分支语句类似,即在条件(表达式)为真的情况下,会执行相应的代码块。不同之处在于,只要条件为真,while 就会一直重复执行那段代码块。
while 语句的语法格式如下:
while 条件表达式:
代码块
这里的代码块,指的是缩进格式相同的多行代码,不过在循环结构中,它又称为循环体。
while 语句执行的具体流程为:首先判断条件表达式的值,其值为真(True)时,则执行代码块中的语句,当执行完毕后,再回过头来重新判断条件表达式的值是否为真,若仍为真,则继续重新执行代码块...如此循环,直到条件表达式的值为假(False),才终止循环。
5.2.2、for循环
for 循环的语法格式如下:
for 迭代变量 in 字符串|列表|元组|字典|集合:
代码块
格式中,迭代变量用于存放从序列类型变量中读取出来的元素,所以一般不会在循环中对迭代变量手动赋值;代码块指的是具有相同缩进格式的多行代码(和 while 一样),由于和循环结构联用,因此代码块又称为循环体。
5.2.3、break和continue
我们知道,在执行 while 循环或者 for 循环时,只要循环条件满足,程序将会一直执行循环体,不停地转圈。但在某些场景,我们可能希望在循环结束前就强制结束循环,Python 提供了 2 种强制离开当前循环体的办法:
-
使用 continue 语句,可以跳过执行本次循环体中剩余的代码,转而执行下一次的循环。
-
只用 break 语句,可以完全终止当前循环。
break 语句可以立即终止当前循环的执行,跳出当前所在的循环结构。无论是 while 循环还是 for 循环,只要执行 break 语句,就会直接结束当前正在执行的循环体。和 break 语句相比,continue 语句的作用则没有那么强大,它只会终止执行本次循环中剩下的代码,直接从下一次循环继续执行。