python

1.1 自学

必须⾃学 ⾃学,是成为⼀名优秀程序员的唯⼀途径,注意不是“途径之⼀”,⽽是“唯⼀途径”,舍此⽆ 他。 有幸遇到过很多优秀程序员,曾向他们请教有关个⼈发展的问题。这些青年才俊,毫⽆例外 都谈到了“⾃学”。⽤不完全归纳法,可以认为优秀程序是“⾃学成才”的,或者说具有较强的 ⾃学能⼒。虽然此结论没有得到严格的证明,但它是多年的经验积累——⼈⽣经验不同于数 学定理,通常难以证明。诚然,如果不认可,亦不能强求。

1.2 操作系统

1.2.1 windows的DMS命令

命令 说明 MD 创建⼦⽬录                       CD 改变当前⽬录,进⼊到指定的⽬录

DIR 显⽰指定位置下的⽬录和⽂件(默认是当前位置)                   TREE 显⽰⽬录结构

COPY 复制⽂件                      REN ⽂件改名命令

DEL 刪除⽂件命令                     DATE 查看⽇期命令

在 Windows 中输⼊命令,不区分⼤⼩写.

建议去看windows下的DOS命令

1.2.2 LINUX操作系统

Linux 是⼀种开源操作系统,它以 Unix 为基础,发明⼈是 Linus Torvalds(如图1-5-7所 ⽰)。这是⼀位令众多程序员膜拜的、为 IT 业做出卓越贡献的开发者,他除了发明 Linux 操作系统之外,还发明了⼀种源码管理系统 Git ,是⽬前⼴泛应⽤的源码管理⼯具。

命令 说明 mkdir 创建⼦⽬录                   cd 改变当前⽬录,进⼊到指定的⽬录

ls 显⽰指定位置下的⽬录和⽂件(默认是当前位置)                    cp 复制⽂件

rm 刪除⽂件命令                       cat 在显⽰器上查看⽂件内容

mv 移动⽂件或⽬录,还可以对其重命名

find 在给定位置按照条件进⾏搜索                                shutdown 关闭计算机

现在⽤的计算机是 Windows 操作系统,建议从以下⽅式中选择⼀种,在⾃ ⼰的计算机上安装 Ubuntu 操作系统,并⼒争将其作为开发和学习的主要环境,⾄少 要有所体验。 ⽅式1:卸载 Windows 操作系统后安装 Ubuntu 系统。特别是针对“⽼旧”计算机,运 ⾏ Windows 系统及应⽤软件,已经“慢吞吞”了,如果改为 Ubuntu 系统,⽴刻会实 现“飞⼀般”的操作。除了卸载原有 Windows 操作系统之外,还可以在性能较好的计 算机上安装双系统,开机时选择将要使⽤的操作系统。具体安装⽅法请参阅 Ubuntu 官⽅⽹站的安装指南(https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overvi ew)或者其他⽹络资料安装。

⽅式2:在计算机上安装虚拟机软件,⽐如 VMware 、VirtualBox ,然后在虚拟机上 安装 Ubuntu系统。

⽅式3:由于 Linux 系统对开发者的友好性,Windows 10 操作系统已经⽀持内置的 Linux ⼦系统,可以参阅相关资料,开启并使⽤⼦系统。 读者若有计划在软件开发这个⽅向上有所深⼊,就不得不摆脱貌似简单实则低效的 ⽤⿏标“点来点去”的操作习惯,改为貌似复杂实则便捷⾼效的“命令⾏”。不论是 1.5.1节的 DOS 命令,还是此处介绍的 Linux 命令,⾄少要熟悉⼀种。

1.2.3 mac os系统

macOS 是美国苹果公司推出的操作系统(注意,历史上这个操作系统的名称有所变更, 2011年及之前称为 Mac OS X ,2012年⾄2015年称 OS X ),主要⽤于其 Macintosh(简称 Mac)系列的个⼈计算机上。 macOS 具有⾮常友好的视窗操作界⾯,并且与硬件配合堪称天⾐⽆缝(毕竟是同⼀家⽣产 的),这赢得了⼤众的欢迎(只是价格不怎么亲民)。对于开发者⽽⾔,图形化操作当然是 必须的。除此之外,前述的“⼿指不离开键盘”完成各种操作,在 macOS 中也能轻松实现, 因为 macOS 是基于 Uninx 的,它与 Linux 同宗同源,所以常⽤的 Linux 命令可以⽤在 macOS 上

1.2.4 IDE

什么是IDE

就是一个集成开发环境

IDE(Integrated Development Environment),全称是集成开发环境 ,是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。

如:pycharm,viscode,

1.3 变量

如下:

x = 3
a = x + 1
print(a)

3

变量名称不以数字开头; 变量名称中可以包含英⽂字母(⼤写和⼩写)、数字以及下划线 _ 。不允许有其 他英⽂状态下的字符,如“+、-、#、!、@”等,也不能有空格。 ⼀般不使⽤单个的l(字母 L 的⼩写)、O(字母 o 的⼤写)、I(字母 i 的⼤ 写)作为变量名称,这也是为了提⾼可读性,避免误解。 ⼀般不⽤内置的 Python 函数来命名,这样会导致以后调⽤该函数的时候⽆法使⽤ 。 变量名称的长度可以任意,但不宜太长.

1.4 查询python内置关键字(保留字)keyword模块

import keyword
print(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']

1.5算数运算符 

运算符 描述 ⽰例 + 两个对象相加 1+2=3

- 得到负数或是⼀个数减去另⼀个数 2-3=-1

* 两个数相乘或是返回⼀个被重复若⼲次的字符串 2*3=6

/ 两个数相除 5/2=2.5

% 两个数相除后所得的余数 5%2=1

// 向下取整,返回两个数相除的整数 5//2=2

** 计算⼀个数的幂运算 5**2=25

1.5.1 加法(+)
2 + 3

5
2.3 + 3.1

5.4

a = 4
b = 6.2
a + b

10.2
1.5.2 减法(-)

如果没有特别定义,运算符 - 实现的两个数字相减——这⾥所说的数字,⽬前暂且是浮点 数、整数,如下操作:

a=4
b=9.9
print(a-b)

-5.9
1.5.3 取相反数

运算符 - 的另外⼀个作⽤就是对某个数字取相反数:

a=-4
print(-(a))

4
1.5.4 乘法(*)

数学中,实现乘法的运算符是 ,但在编程语⾔中,使⽤的是键盘上的 * 。如果相乘的 是两个数字——⽬前讨论的是浮点数、整数,那么与数学中的运算结果⼀致。

a = 4 * 4
print(a)

16

对运算符 * 的描述中还有“返回⼀个被重复若⼲次的字符串” 

1.5.5 除法(/ % //)

学中表⽰两个数相除,有多种形式,⽐如 。在 Python 语⾔中只能选⽤⼀ 种符号,对于 Python 3.x ,使⽤ / 符号作为除法运算符,计算结果与数学中的除法运算符 ÷ 计算结果相同。

>> 5 / 2
2.5
>>> 4.2 / 2
2.1

 与除法有关的符号除了 / 之外,还有 % 和 //

1.5.6 //向下取整

运算符 // 的含义是“向下取整”

>> 5 / 2
2.5
>>> 5 // 2
2

5 / 2 的值是 2.5 ,结合图3-2-1所⽰的“向下取整”含义, “下边”的整数是 ,故 5 // 2 的结果是 2。 再来看负数情况:

 

>> -5 / 2
-2.5
>>> -5 // 2
-3

显然 “下边”的整数是 ,所以 -5 // 2 的结果为 -3 。 ⽤ // 按照“向下取整”原则得到的结果,也就是两个数字相除所得的商

1.5.7% 两个数相除后的余数
a = 5 % 2
print(a)

1

 

>> 7 // -9
-1
>>> 7 % -9
-2
1.5.8 幂**   2的3次方

在数学中,若⼲个数相乘可以写成该数字的⼏次幂,如 即为 。在 Python 中 ⽤ ** 运算符——两个乘法运算符,中间不能有空格——表⽰幂运算

>> 2 ** 3
8
>>> 2 ** -3
0.125
1.5.9 科学计数法( a  X 10n)(1e10)

然表3-2-1中没有列出科学计数法的符号——其实它不是⼀个运算符,但由于在科学计算 中会经常⽤到,所以此处单独作为⼀项。在数学上,⼀个实数可以写成实数 与 的 积:a  X 10n  其中:

n必须是整数;

a是实数,通常 1<=  a <=,有时a 也会不在此范围,届时要调整n的⼤⼩。

这种表⽰数字的⽅法称为科学计数法(Scientific Notation),由阿基⽶德提出。 在 Python 中,为科学计数法设计了专有表⽰⽅式:

>> 1e10
10000000000.0
>>> 1E10
10000000000.0

 ⾯两种表⽰⽅法,均为 ——其中符号 e 不区分⼤⼩写。特别要注意,这是 Python 中⽐较特殊的现象,在其他⽅⾯通常要求区分⼤⼩写。

e后⾯如果是负整数,例如:

a = 2.3e-4
print(a)

0.00023

2.3e-4即表示2.3 X 10-4

任何⽤科学记数法表⽰的数,都是浮点数类型

>>> a = 2.3E-4
>>> type(a)
<class 'float'>
>>> b = 1E1
>>> b
10.0
>>> type(b)
<class 'float'>

如果表⽰ ,符号E前⾯是不是也可以省略数字 呢? 

>> E8
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'E8' is not defined

在⼀个数学算式中,如果有多个表3-2-1中的运算符,在数学称为“混合运算”。⽤ Python 能实现混合运算,且运算优先级与数学上的规定保持⼀致。

>>> 3 ** 2 + 4 / 2 - 3 + 2
10.0

 数学运算中,会⽤圆括号 明确优先运算的部分,它也被引⼊到了 Python 语⾔中,⽽ 且在 Python 中还特别提倡使⽤圆括号,这样能提⾼表达式的可读性——代码的可读性强, 是编程的第⼀原则。

>> 3 ** 2 + 4 / 2 - (3 + 2)
#3**2=9  + 2-5
6.0

Python 中的“⼤整数”不溢出现象,但是对 于浮点数运算⽽⾔,若超出了中央处理器所能允许浮点数范围,会出现算术溢出。

a = 1.9 ** 10000
print(a)


Traceback (most recent call last):
  File "D:\pythonProject\student\基础·.py", line 1, in <module>
    a = 1.9**10000
OverflowError: (34, 'Result too large')

 所以,在进⾏浮点数运算的时候要注意了。 但是,如果是⼀个⽤科学计数法表⽰的浮点数超出了系统的浮点数范围,Python 会给出另 外⼀种处理,例如:

>>> n = 2E400
>>> n
inf
>>> type(n)
<class 'float'>
>>> 10 ** 400
100000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000
00000
>>> 10.0 ** 400
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')#溢出错误:(34,“结果太大”)

 此处的 2E400 即 ,这个数字已经⼤于了宇宙中原⼦的总数(按照⽬前理论估 算,在可观测宇宙中的原⼦总数⼤约是 ),但是 Python 没有针对 2E400 出现算术溢 出,⽽是令其值为 inf,它表⽰“⽆穷⼤”,并且是⼀个浮点数——这是 Python 的规定,请 勿⽤数学上的规定来评判。 顺便⽐较 10 ** 400 与 10.0 ** 400的区别:前者返回的是整数——不会溢出,后者返回 结果应该是浮点数,溢出了。

1.6 用函数计算match库

术运算符能完成的是基本运算,为了便于计算,数学上还定义了其他⼀些常见函数,⽐如 三⾓函数、对数函数等。Python 语⾔中,有多种⽅式能够实现对常见函数计算,本节仅以 内置函数和标准库中的 math 模块为例给予这⽅⾯的简要介绍,更多有关数学计算问题,请 参阅《机器学习数学基础》

1.7 内置函数

Python 内置函数(Built-in Functions)是在本地计 算机中配置好 Python 开发环境之后就已经可以使⽤的函数,不需要单独定义。在第7章会 学习定义函数的⽅法,⽽内置函数是已经定义好了的,拿过来就可使⽤,正所谓“开箱即 ⽤”,但数量有限,

1.7.1 int() 和 float()类型转换

int() 和 float() 两个内置函数与3.1节所学习过的两个内置对象类型同名,⽤它们能够创 建相应对象或实现对象类型转化——“创建”的⽅法,此处仅讨论“类型转化”。

 

>>> int(3.14)
3
>>> int(-3.14)
-3
>>> int(3.56)
3
>>> int(-3.56)
-3

 从上述操作结果不难总结出如下结论: int() 可以将浮点数转化为整数; int() 只是截取整数部分,不是“向下取整”,也不是“四舍五⼊”

看来这个函数不复杂,但“⿇雀虽⼩五脏俱全”,解剖它就能够对所有内置函数有基本了解。 请继续按照下述⽅式输⼊代码

help(int)

这⾥所⽤的 help() 也是⼀个内置函数,可以在表3-3-1中找到。其参数是 int 。注 意,int 后⾯没有 () ,此时表⽰的是函数 int() 对象。 然后敲回车键,会呈现如图3所⽰的内容(图中是部分内容截取),按向下键或滚动⿏ 标,可以查看没有显⽰的部分。 

与查看 int() 函数的帮助⽂档的操作⼀样,在交互模式中输⼊ help(float) 即可查看 float() 函数的帮助⽂档,亦或在 Python 官⽅⽂档中查看该内容。建议读者认真阅读该⽂ 档,并对照如下操作理解其含义

>>> float(3)
 3.0
1.7.2 divmod()同时返回两个数相除所得的商和余数

函数 divmod() 会同时返回两个数相除所得的商和余数。在交互模式中查看其帮助⽂档(输 ⼊ help(divmod) ),会看到如下所⽰的简洁描述:

divmod(x, y, /)
    Return the tuple (x//y, x%y). Invariant: div*y + mod == x.

divmod() 的参数是两个实数 x 和 y ,返回的是 tuple类型对象(关于 tuple 请参阅第4 章4.4节),其中包括两部分,第⼀部分是 x//y ——表⽰商,第⼆部分是 x%y ——表⽰余 数。在⽂档中的式⼦: div*y + mod == x ,其中 div 是商,mod 是余数,这与说明 // 和 % 运算符是完全⼀致,请对照阅读。⽤以下操作熟悉这个函数的调⽤⽅法 

>>> divmod(5, 2)
(2, 1)
>>> divmod(-5, 2)
(-3, 1)
>>> divmod(7, -9)
(-1, -2)
1.7.3 pow()函数作⽤与运算符 ** 相同求幂

⼀般情况下,函数 pow() 的作⽤与运算符 ** 相同,即计算某个数的幂,例如:

>>> 2 ** 3
8
a = pow(3,2)
print(a)

9

 其中 pow() 的第⼀个参数 2 是底数,第⼆个参数 3 是指数。

an:其中 a叫做底数, n叫做指数,an 的结果叫做幂。

如果读者查看其⽂档,会发现对 pow()参数的描述⽅式有如下两种:

帮助⽂档中:pow(base, exp, mod=None) ;

官⽅⽂档中:pow(base, exp[, mod]) 。 

其中的 base 和 exp 没有什么异议,重点看第三个参数: mod=None 表⽰此参数默认值是 None ,( None 是⼀个 Python 对象,表⽰没有定义或者没有值);[, mod] 表⽰此参数 可以省略,当省略的时候与 mod=None 等效.

如果对参数 mod 赋值, 函数 pow() 与 ** 运算符就有差别了。当 mod 不为 None 时,则计 算 base ** exp % mod ,并返回表达式的值(mod 为⾮零整数,exp⼤于零。建议读者通 过⽂档理解 exp⼩于零时的计算过程)

>>> 2 ** 3 % 5
3
>>> pow(2, 3, 5)
3

以上得到了2的3次方=8,再除以 5所得的余数5.

与运算符 *** 相⽐,通常 pow() 函数计算性能更好。

1.7.4 round()实现对⼀个实数的四舍五⼊

使⽤ round() 函数能够实现对⼀个实数的四舍五⼊——针对⼗进制数字⽽⾔。在交互模式 中完成如下操作,并结合数学中的“四舍五⼊”含义理解操作结果

>> round(3.14, 1)
3.1
>>> round(3.56)
4
>>> round(3.56, 0)
4.0
>>> round(356, -2)
400
>>> round(356, -1)
360
>>> round(-3.56, 1)
-3.6
>>> round(-356, -1)
-360

读者阅读官⽅⽂档(https://docs.python.org/3/library/functions.html#round),会看 到如下⽰例:

>>> round(2.675, 2)
2.67

根据数学知识, 按照四舍五⼊原则保留两位⼩数,结果应为 ,然⽽此处返回值 是 2.67 。在官⽅⽂档中明确说明:“This is not a bug”,并且给出了解释 

 1.7.5 max() 选出若⼲个数中的最⼤值

内置函数 max() 能够选出若⼲个数中的最⼤值,例如:

a = max(3, 3.14, 7, 28)
print(a)

28
1.7.5 min()返回数字中的最小值

 manx() 的参数,每个数字之间⽤英⽂的逗号 , 隔开。同理,min() 函数则返回⼀系 列数字中的最⼩值。 

a = min(3, 3.14, 7, 28)
print(a)

3

两个函数,除了可以如同以上那样使⽤,其参数还可以是“可迭代对象”(iterable)

1.7.6 dir()能够返回参数对象的属性和⽅法

如:

import math
print(dir(math))

['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

1.8标准库math模块

准库中的 math 模块主要提供初等数学中常⽤函数,官⽅⽂档地址是 https://docs.python .org/3/library/math.html。请在本地交互模式中,输⼊ import math ,然后敲回车键,如 下所⽰:

import math
print(dir(math))

['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

 这⾥使⽤了内置函数 dir() ,它能够返回参数对象的属性和⽅法——在第2章2.4节初步接 触了对象的“属性”和“⽅法”

对于 dir(math) 的返回结果,也 可以理解为模块 math ⾥⾯提供的函数。不妨浏览⼀番这些函数名称,并与记忆中的初等数 学常⽤函数对⽐

这些函数怎么⽤?以余弦函数 cos 为例,根据⾃学经验,应该先看⼀看这个函数的⽂档:

help(match.cos)

上述写法,不能直接写 help(cos) ,因为函数 cos 是模块 math 的⼀员,注释(1) 引⼊的是这个模块,当调⽤其中的函数时,必须借助模块的名称 。

执⾏上述语句,可以看到 math.cos 的帮助⽂档

cos(x, /)
Return the cosine of x (measured in radians)
1.8.1math.cos()是以弧度(rad )为单位,并返回该值的余 弦

此可知,math.cos() 函数的中的参数 x 是以弧度(rad )为单位,并返回该值的余 弦。

下⾯以计算 为例演⽰ math.cos() 的使⽤⽅法:

>> alpha = 60 / 180 * math.pi # (2)
>>> math.cos(alpha) # (3)
0.5000000000000001

 注释(2)将以⾓度为单位60°的 转化为以弧度为单位的 3分之1乘以π,但此处⽤浮点数表⽰。其中 还使⽤了 math.pi ,其值即为

>> math.pi
3.141592653589793

 注释(3)即为调⽤余弦函数,并得到了返回值——有点奇怪,暂不⽤管太多。 

>>> round(math.cos(math.pi/4) + math.log10(5) * math.exp(2), 2)
5.87

1.9. fractions 模块 

 根据之前所学,如果在 Python 中表⽰三分之一 ,只能⽤ 1/3 实现,即以浮点数近似地表⽰。

>>> 1/3
0.3333333333333333

有没有实现精确表⽰的⽅法呢?必须得有!这就是标准库中的 fractions 模块所要解决的 问题。

>> import fractions # (4)
>>> a = fractions.Fraction(60, 180) # (5)
>>> a
Fraction(1, 3)

 

 

>> 1 / 3 + 1 / 2
0.8333333333333333

 

 

import fractions
a = fractions.Fraction(1,3)
b = fractions.Fraction(1,2)
s = a + b
print(s)

5/6

此就实现了分数的精确计算。

输出(print函数)

print()在括号中加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下:

print('hello world')
hello world

 print()函数也可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出:

print('The quick brown fox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog

 print()会依次打印每个字符串,遇到逗号“,”会输出一个空格.

print()也可以打印整数,或者计算结果:

print(300)

300
print(100 + 200)

300

 因此,我们可以把计算100 + 200的结果打印得更漂亮一点:

print('100 + 200',100+200)

100 + 200= 300

注意,对于100 + 200,Python解释器自动计算出结果300,但是,'100 + 200 ='是字符串而非数学公式,Python把它视为字符串。

输入(input)

现在,你已经可以用print()输出你想要的结果了。但是,如果要让用户从电脑输入一些字符怎么办?Python提供了一个input(),可以让用户输入字符串,并存放到一个变量里。比如输入用户的名字:

name = input()

当你输入name = input()并按下回车后,Python交互式命令行就在等待你的输入了。这时,你可以输入任意字符,然后按回车后完成输入。

输入完成后,不会有任何提示,Python交互式命令行又回到>>>状态了。那我们刚才输入的内容到哪去了?答案是存放到name变量里了。可以直接输入name查看变量内容:

name = input()
print(name)

数据类型

计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值。但是,计算机能处理的远不止数值,还可以处理文本、图形、音频、视频、网页等各种各样的数据,不同的数据,需要定义不同的数据类型。在Python中,能够直接处理的数据类型有以下几种:

整数(int)

Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1100-80800,等等。

计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff000xa5b4c3d2,等等。

对于很大的数,例如10000000000,很难数清楚0的个数。Python允许在数字中间以_分隔,因此,写成10_000_000_00010000000000是完全一样的。十六进制数也可以写成0xa1b2_c3d4

浮点数(float)

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x109和12.3x108是完全相等的。浮点数可以用数学写法,如1.233.14-9.01,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。

整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。

字符串(str)

字符串是以单引号'或双引号"括起来的任意文本,比如'abc'"xyz"等等。请注意,''""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有abc这3个字符。如果'本身也是一个字符,那就可以用""括起来,比如"I'm OK"包含的字符是I'm,空格,OK这6个字符。

如果字符串内部既包含'又包含"怎么办?可以用转义字符\来标识,比如:

'I\'m \"OK\"!'

表示的字符串内容是:

I'm "OK"!

 转义字符(\n表示换行,\t表示制表符,字符\本身也要转义,)

转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\,可以在Python的交互式命令行用print()打印字符串看看:

print('I\'m ok.')

print('I\'m learning\nPython.')

print('\\\n\\')
I'm ok.
I'm learning
Python.
\
\

 如果字符串里面有很多字符都需要转义,r''表示''内部的字符串默认不转义

如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r''表示''内部的字符串默认不转义,可以自己试试:

>>> print('\\\t\\')
\       \
>>> print(r'\\\t\\')
\\\t\\

如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用'''...'''的格式表示多行内容,可以自己试试:

>>> print('''line1
... line2
... line3''')
line1
line2
line3

上面是在交互式命令行内输入,注意在输入多行内容时,提示符由>>>变为...,提示你可以接着上一行输入,注意...是提示符,不是代码的一部分:

┌────────────────────────────────────────────────────────┐
│Command Prompt - python                           _ □ x │
├────────────────────────────────────────────────────────┤
│>>> print('''line1                                      │
│... line2                                               │
│... line3''')                                           │
│line1                                                   │
│line2                                                   │
│line3                                                   │
│                                                        │
│>>> _                                                   │
│                                                        │
│                                                        │
│                                                        │
└────────────────────────────────────────────────────────┘

当输入完结束符```和括号)后,执行该语句并打印结果。

当输入完结束符```和括号)后,执行该语句并打印结果。

如果写成程序并存为.py文件,就是:

print('''line1
line2
line3''')

布尔值(True False)(and or not)

布尔值和布尔代数的表示完全一致,一个布尔值只有TrueFalse两种值,要么是True,要么是False,在Python中,可以直接用TrueFalse表示布尔值(请注意大小写),也可以通过布尔运算计算出来:

>>> True
True
>>> False
False
>>> 3 > 2
True
>>> 3 > 5
False

布尔值可以用andornot运算。

and运算是与运算,只有所有都为Trueand运算结果才是True

>>> True and True
True
>>> True and False
False
>>> False and False
False
>>> 5 > 3 and 3 > 1
True

or运算是或运算,只要其中有一个为Trueor运算结果就是True

>>> True or True
True
>>> True or False
True
>>> False or False
False
>>> 5 > 3 or 1 > 3
True

not运算是非运算,它是一个单目运算符,把True变成FalseFalse变成True

>>> not True
False
>>> not False
True
>>> not 1 > 2
True

布尔值经常用在条件判断中,比如:

if age >= 18:
    print('adult')
else:
    print('teenager')

空值(None)

空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

变量(等号=是赋值语句)

变量的概念基本上和初中代数的方程变量是一致的,只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。

变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和_的组合,且不能用数字开头,比如:

a = 1

变量a是一个整数。

t_007 = 'T007'

变量t_007是一个字符串。

Answer = True

变量Answer是一个布尔值True

在Python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如:

a = 123 # a是整数
print(a)
a = 'ABC' # a变为字符串
print(a)

123
ABC

这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如Java是静态语言,赋值语句如下(// 表示注释):

int a = 123; // a是整数类型变量
a = "ABC"; // 错误:不能把字符串赋给整型变量

和静态语言相比,动态语言更灵活,就是这个原因。

请不要把赋值语句的等号等同于数学的等号。比如下面的代码:

x = 10
x = x + 2

如果从数学上理解x = x + 2那无论如何是不成立的,在程序中,赋值语句先计算右侧的表达式x + 2,得到结果12,再赋给变量x。由于x之前的值是10,重新赋值后,x的值变成12

最后,理解变量在计算机内存中的表示也非常重要。当我们写:

a = 'ABC'

时,Python解释器干了两件事情:

  1. 在内存中创建了一个'ABC'的字符串;

  2. 在内存中创建了一个名为a的变量,并把它指向'ABC'

也可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据,例如下面的代码:

a = 'ABC'
b = a
a = 'XYZ'
print(b)

ABC

最后一行打印出变量b的内容到底是'ABC'呢还是'XYZ'?如果从数学意义上理解,就会错误地得出ba相同,也应该是'XYZ',但实际上b的值是'ABC',让我们一行一行地执行代码,就可以看到到底发生了什么事:

执行a = 'ABC',解释器创建了字符串'ABC'和变量a,并把a指向'ABC'

py-var-code-1

执行b = a,解释器创建了变量b,并把b指向a指向的字符串'ABC'

py-var-code-2

执行a = 'XYZ',解释器创建了字符串'XYZ',并把a的指向改为'XYZ',但b并没有更改:

py-var-code-3

所以,最后打印变量b的结果自然是'ABC'了。

常量(就是不能变的变量)(inf无穷大)

所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量:

PI = 3.14159265359

但事实上PI仍然是一个变量,Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量PI的值,也没人能拦住你。

最后解释一下整数的除法为什么也是精确的。在Python中,有两种除法,一种除法是/

>>> 10 / 3
3.3333333333333335

/除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:

>>> 9 / 3
3.0

还有一种除法是//,称为地板除,两个整数的除法仍然是整数:

>>> 10 // 3
3

你没有看错,整数的地板除//永远是整数,即使除不尽。要做精确的除法,使用/就可以。

因为//除法只取结果的整数部分,所以Python还提供一个余数运算,可以得到两个整数相除的余数:

>>> 10 % 3
1

无论整数做//除法还是取余数,结果永远是整数,所以,整数运算结果永远是精确的。

Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。

对变量赋值x = y是把变量x指向真正的对象,该对象是变量y所指向的。随后对变量y的赋值不影响变量x的指向。

注意:Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647。 

Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。

字符编码

我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295

由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122

但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

因此,Unicode字符集应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

Unicode标准也在不断发展,但最常用的是UCS-16编码,用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。

现在,捋一捋ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。

字母A用ASCII编码是十进制的65,二进制的01000001

字符0用ASCII编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的;

汉字已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101

你可以猜测,如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001

新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

字符ASCIIUnicodeUTF-8
A0100000100000000 0100000101000001
x01001110 0010110111100100 10111000 10101101

从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

搞清楚了ASCII、Unicode和UTF-8的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:

在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:

浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器:

web-utf-8

所以你看到很多网页的源码上会有类似<meta charset="UTF-8" />的信息,表示该网页正是用的UTF-8编码。

Python的字符串

搞清楚了令人头疼的字符编码问题后,我们再来研究Python的字符串。

在最新的Python 3版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言,例如:

>>> print('包含中文的str')
包含中文的str
ord()函数 (获取字符的整数表示)
chr()函数把编码转换为对应的字符

对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:

print(ord('A'))

print(ord('中'))
print(chr(66))

print(chr(25991))



65
20013
B
文

如果知道字符的整数编码,还可以用十六进制这么写str

>>> '\u4e2d\u6587'
'中文'

两种写法完全是等价的。

由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes

Python对bytes类型的数据用带b前缀的单引号或双引号表示:

x = b'ABC'

要注意区分'ABC'b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字符都只占用一个字节。

encode()方法可以编码为指定的bytes(字节)
b

以Unicode表示的str通过encode()方法可以编码为指定的bytes,例如:

print('ABC'.encode('ascii'))

print('中文'.encode('utf-8'))

print('中文'.encode('ascii'))




b'ABC'
b'\xe4\xb8\xad\xe6\x96\x87'
Traceback (most recent call last):
  File "D:\pythonProject\student\基础·.py", line 5, in <module>
    print('中文'.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

Process finished with exit code 1

纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。

bytes中,无法显示为ASCII字符的字节,用\x##显示。

decode()方法要把bytes变为str

反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

如果bytes中包含无法解码的字节,decode()方法会报错:

>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
  ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
errors='ignore'忽略错误的字节

如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:

>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
 len()函数计算包含多少个字符

要计算str包含多少个字符,可以用len()函数:

>>> len('ABC')
3
>>> len('中文')
2

len()函数计算的是str的字符数,如果换成byteslen()函数就计算字节数:

>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6

可见,1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。

在操作字符串时,我们经常遇到strbytes的互相转换。为了避免乱码问题,应当始终坚持使用UTF-8编码对strbytes进行转换。

由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

格式化

最后一个常见的问题是如何输出格式化的字符串。我们经常会输出类似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'之类的字符串,而xxx的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式。

py-str-format

在Python中,采用的格式化方式和C语言是一致的,用%实现,举例如下:

print( 'Hello, %s' % 'world')
'Hello, world'
print('Hi, %s, you have $%d.' % ('Michael', 1000000))
'Hi, Michael, you have $1000000.'

你可能猜到了,%运算符就是用来格式化字符串的。在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。

占位符

常见的占位符有:

占位符替换内容
%d整数
%f浮点数
%s字符串
%x十六进制整数

 其中,格式化整数和浮点数还可以指定是否补0和整数与小数的位数:

print('%2d-%02d' % (3, 1))
print('%.2f' % 3.1415926)
 3-01
3.14

如果你不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串:

>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'

有些时候,字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%

>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'

format()格式化字符串的方法是

另一种格式化字符串的方法是使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}{1}……,不过这种方式写起来比%要麻烦得多:

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'
f-string  格式化字符串的方法是
f

最后一种格式化字符串的方法是使用以f开头的字符串,称之为f-string,它和普通字符串不同之处在于,字符串如果包含{xxx},就会以对应的变量替换:

>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62

上述代码中,{r}被变量r的值替换,{s:.2f}被变量s的值替换,并且:后面的.2f指定了格式化参数(即保留两位小数),因此,{s:.2f}的替换结果是19.62

小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点,并用字符串格式化显示出'xx.x%',只保留小数点后1位:、

s1=int(input('请输入去年的成绩'))
s2=int(input('请输入今年的成绩'))
r=(s2-s1)/s1*100
print('小明的成绩提升了%2.1f%%'%r)
print(f'小明的成绩提升了{r:.1f}%')

list(集合)

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。

比如,列出班里所有同学的名字,就可以用一个list表示:

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']

变量classmates就是一个list。用len()函数可以获得list元素的个数:

>>> len(classmates)
3

用索引来访问list中每一个位置的元素,记得索引是从0开始的:

>>> classmates[0]
'Michael'
>>> classmates[1]
'Bob'
>>> classmates[2]
'Tracy'
>>> classmates[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range#索引错误:列表索引超出范围

当索引超出了范围时,Python会报一个IndexError错误,所以,要确保索引不要越界,记得最后一个元素的索引是len(classmates) - 1

如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素:

>>> classmates[-1]
'Tracy'

以此类推,可以获取倒数第2个、倒数第3个:

>>> classmates[-2]
'Bob'
>>> classmates[-3]
'Michael'
>>> classmates[-4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

当然,倒数第4个就越界了。

append()方法可以往list中追加元素到末尾

list是一个可变的有序表,所以,可以往list中追加元素到末尾:

classmates = ['Michael', 'Bob', 'Tracy']

classmates.append('Adam')
print(classmates)


['Michael', 'Bob', 'Tracy', 'Adam']
insert()可以把元素插入到指定的位置,索引添加指定位置

也可以把元素插入到指定的位置,比如索引号为1的位置:

classmates = ['Michael', 'Bob', 'Tracy']

classmates.append('Adam')
print(classmates)
classmates.insert(1, 'Jack')
print(classmates)


['Michael', 'Bob', 'Tracy', 'Adam']
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
pop()删除list末尾的元素

要删除list末尾的元素,用pop()方法:

classmates = ['Michael', 'Bob', 'Tracy']

classmates.append('Adam')
print(classmates)
classmates.insert(1, 'Jack')
print(classmates)
classmates.pop()

print(classmates)
classmates.pop()

print(classmates)


['Michael', 'Bob', 'Tracy', 'Adam']
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
['Michael', 'Jack', 'Bob', 'Tracy']
['Michael', 'Jack', 'Bob']
pop(i)删除指定位置的元素,其中i是索引位置

要删除指定位置的元素,用pop(i)方法,其中i是索引位置:

classmates = ['Michael', 'Bob', 'Tracy']

classmates.append('Adam')
print(classmates)

classmates.pop(1)
print( classmates)

['Michael', 'Bob', 'Tracy', 'Adam']
['Michael', 'Tracy', 'Adam']
某个元素替换成别的元素

要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:

classmates = ['Michael', 'Bob', 'Tracy']

classmates.append('Adam')
print(classmates)

classmates[1] = 'Sarah'
print( classmates)

['Michael', 'Bob', 'Tracy', 'Adam']
['Michael', 'Sarah', 'Tracy', 'Adam']

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值