Python 基础语法一

本贴最后更新于 2354 天前,其中的信息可能已经斗转星移

数据类型

一、整数

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

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

二、浮点数

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

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

三、字符串

字符串是以 ''"" 括起来的任意文本,比如**'abc'"xyz"等等。请注意,''""**本身只是一种表示方式,不是字符串的一部分,因此,字符串 'abc' 只有 a,b,c 这 3 个字符。

四、布尔值

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

布尔值可以用 andornot 运算。

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

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

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

五、空值

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

print 语句可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下:

print 'hello, world'

Python 的注释

Python 的注释以 # 开头,后面的文字直到行尾都算注释

# 这一行全部都是注释...
print 'hello' # 这也是注释

Python 变量

在 Python 中,变量的概念基本上和初中代数的方程变量是一致的。

例如,对于方程式 y=x*x x 就是变量。当 x=2 时,计算结果是 4,当 x=5 时,计算结果是 25

只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。

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

a = 1

变量 a 是一个整数。

t_007 = 'T007'

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

a = 123    # a是整数
print a
a = 'imooc'   # a变为字符串
print a

这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。

静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如 Java 是静态语言,赋值语句如下(// 表示注释):

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

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

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

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

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

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

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

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

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

Python 中定义字符串

前面我们讲解了什么是字符串。字符串可以用 '' 或者 "" 括起来表示。

如果字符串本身包含 ' 怎么办?比如我们要表示字符串 I'm OK,这时,可以用 " " 括起来表示:

"I'm OK"

类似的,如果字符串包含 ",我们就可以用 ' ' 括起来表示:

'Learn "Python" in imooc'

如果字符串既包含 ' 又包含 " 怎么办?

这个时候,就需要对字符串的某些特殊字符进行“转义”,Python 字符串用 \ 进行转义。

要表示字符串 Bob said "I'm OK".
由于 ' 和 " 会引起歧义,因此,我们在它前面插入一个 \ 表示这是一个普通字符,不代表字符串的起始,因此,这个字符串又可以表示为

'Bob said \"I\'m OK\".'

**注意:**转义字符 \ 不计入字符串的内容中。

常用的转义字符还有:

\n 表示换行
\t 表示一个制表符
\\ 表示 \ 字符本身

Python 中 raw 字符串与多行字符串

如果一个字符串包含很多需要转义的字符,对每一个字符都进行转义会很麻烦。为了避免这种情况,我们可以在字符串前面加个前缀 r ,表示这是一个 raw 字符串,里面的字符就不需要转义了。例如:

r'\(~_~)/ \(~_~)/'

但是 r'...' 表示法不能表示多行字符串,也不能表示包含 '" 的字符串(为什么?)

如果要表示多行字符串,可以用 '''...''' 表示:

'''Line 1
Line 2
Line 3'''

上面这个字符串的表示方法和下面的是完全一样的:

'Line 1\nLine 2\nLine 3'

还可以在多行字符串前面添加 r,把这个多行字符串也变成一个 raw 字符串:

r'''Python is created by "Guido".
It is free and easy to learn.
Let's start learn Python in imooc!'''

Python 中 Unicode 字符串

字符串还有一个编码问题。

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用 8 个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是 255(二进制 11111111=十进制 255),0 - 255 被用来表示大小写英文字母、数字和一些符号,这个编码表被称为 ASCII 编码,比如大写字母 A 的编码是 65,小写字母 z 的编码是 122。

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

类似的,日文和韩文等其他语言也有这个问题。为了统一所有文字的编码,Unicode 应运而生。Unicode 把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

Unicode 通常用两个字节表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为 0 就可以。

因为 Python 的诞生比 Unicode 标准发布的时间还要早,所以最早的 Python 只支持 ASCII 编码,普通的字符串'ABC'在 Python 内部都是 ASCII 编码的。

Python 在后来添加了对 Unicode 的支持,以 Unicode 表示的字符串用 u'...'表示,比如:

print u'中文'
中文

注意: 不加 u ,中文就不能正常显示。

Unicode 字符串除了多了一个 u 之外,与普通字符串没啥区别,转义字符和多行表示法仍然有效:

转义:

u'中文\n日文\n韩文'

多行:

u'''第一行
第二行'''

raw+ 多行:

ur'''Python的Unicode字符串支持"中文",
"日文",
"韩文"等多种语言'''

如果中文字符串在 Python 环境下遇到 UnicodeDecodeError,这是因为.py 文件保存的格式有问题。可以在第一行添加注释

# -*- coding: utf-8 -*-

目的是告诉 Python 解释器,用 UTF-8 编码读取源代码。然后用 Notepad++ 另存为... 并选择 UTF-8 格式保存。

Python 中整数和浮点数

Python 支持对整数和浮点数直接进行四则混合运算,运算规则和数学上的四则运算规则完全一致。

基本的运算:

1 + 2 + 3   # ==> 6
4 * 5 - 6   # ==> 14
7.5 / 8 + 2.1   # ==> 3.0375

使用括号可以提升优先级,这和数学运算完全一致,注意只能使用小括号,但是括号可以嵌套很多层:

(1 + 2) * 3    # ==> 9
(2.2 + 3.3) / (1.5 * (9 - 0.3))    # ==> 0.42145593869731807

和数学运算不同的地方是,Python 的整数运算结果仍然是整数,浮点数运算结果仍然是浮点数:

1 + 2    # ==> 整数 3
1.0 + 2.0    # ==> 浮点数 3.0

但是整数和浮点数混合运算的结果就变成浮点数了:

1 + 2.0    # ==> 浮点数 3.0

为什么要区分整数运算和浮点数运算呢?这是因为整数运算的结果永远是精确的,而浮点数运算的结果不一定精确,因为计算机内存再大,也无法精确表示出无限循环小数,比如 0.1 换成二进制表示就是无限循环小数。

那整数的除法运算遇到除不尽的时候,结果难道不是浮点数吗?我们来试一下:

11 / 4    # ==> 2

令很多初学者惊讶的是,Python 的整数除法,即使除不尽,结果仍然是整数,余数直接被扔掉。不过,Python 提供了一个求余的运算 % 可以计算余数:

11 % 4    # ==> 3

如果我们要计算 11 / 4 的精确结果,按照“整数和浮点数混合运算的结果是浮点数”的法则,把两个数中的一个变成浮点数再运算就没问题了:

11.0 / 4    # ==> 2.75

Python 中布尔类型

我们已经了解了 Python 支持布尔类型的数据,布尔类型只有 TrueFalse 两种值,但是布尔类型有以下几种运算:

与运算:只有两个布尔值都为 True 时,计算结果才为 True。

True and True   # ==> True
True and False   # ==> False
False and True   # ==> False
False and False   # ==> False

或运算:只要有一个布尔值为 True,计算结果就是 True。

True or True   # ==> True
True or False   # ==> True
False or True   # ==> True
False or False   # ==> False

非运算:把 True 变为 False,或者把 False 变为 True:

not True   # ==> False
not False   # ==> True

布尔运算在计算机中用来做条件判断,根据计算结果为 True 或者 False,计算机可以自动执行不同的后续代码。

在 Python 中,布尔类型还可以与其他数据类型做 and、or 和 not 运算,请看下面的代码:

a = True
print a and 'a=T' or 'a=F'

计算结果不是布尔类型,而是字符串 'a=T',这是为什么呢?

因为 Python 把 0空字符串''None 看成 False,其他数值和非空字符串都看成 True,所以:

True and 'a=T' 计算结果是 'a=T'
继续计算 'a=T' or 'a=F' 计算结果还是 'a=T'

要解释上述结果,又涉及到 and 和 or 运算的一条重要法则:短路计算。

  1. 在计算 a and b 时,如果 a 是 False,则根据与运算法则,整个结果必定为 False,因此返回 a;如果 a 是 True,则整个计算结果必定取决与 b,因此返回 b。

2. 在计算 a or b 时,如果 a 是 True,则根据或运算法则,整个计算结果必定为 True,因此返回 a;如果 a 是 False,则整个计算结果必定取决于 b,因此返回 b。

所以 Python 解释器在做布尔运算时,只要能提前确定计算结果,它就不会往后算了,直接返回结果。

Python 创建 list

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

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

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

list 是数学意义上的有序集合,也就是说,list 中的元素是按照顺序排列的。

构造 list 非常简单,按照上面的代码,直接用 [ ] 把 list 的所有元素都括起来,就是一个 list 对象。通常,我们会把 list 赋值给一个变量,这样,就可以通过变量来引用 list:

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates # 打印classmates变量的内容
['Michael', 'Bob', 'Tracy']

由于 Python 是动态语言,所以 list 中包含的元素并不要求都必须是同一种数据类型,我们完全可以在 list 中包含各种数据:

>>> L = ['Michael', 100, True]

一个元素也没有的 list,就是空 list:

>>> empty_list = []

Python 按照索引访问 list

由于 list 是一个有序集合,所以,我们可以用一个 list 按分数从高到低表示出班里的 3 个同学:

>>> L = ['Adam', 'Lisa', 'Bart']

那我们如何从 list 中获取指定第 N 名的同学呢?方法是通过索引来获取 list 中的指定元素。

需要特别注意的是,索引从 0 开始,也就是说,第一个元素的索引是 0,第二个元素的索引是 1,以此类推。

因此,要打印第一名同学的名字,用 L[0]:

>>> print L[0]
Adam

要打印第二名同学的名字,用 L[1]:

>>> print L[1]
Lisa

要打印第三名同学的名字,用 L[2]:

>>> print L[2]
Bart

要打印第四名同学的名字,用 L[3]:

>>> print L[3]
Traceback (most recent call last):
  File "", line 1, in 
IndexError: list index out of range

报错了!IndexError 意思就是索引超出了范围,因为上面的 list 只有 3 个元素,有效的索引是 0,1,2。

所以,使用索引时,千万注意不要越界

Python 之倒序访问 list

我们还是用一个 list 按分数从高到低表示出班里的 3 个同学:

>>> L = ['Adam', 'Lisa', 'Bart']

这时,老师说,请分数最低的同学站出来。

要写代码完成这个任务,我们可以先数一数这个 list,发现它包含 3 个元素,因此,最后一个元素的索引是 2:

>>> print L[2]
Bart

有没有更简单的方法?

有!

Bart 同学是最后一名,俗称倒数第一,所以,我们可以用 -1 这个索引来表示最后一个元素:

>>> print L[-1]
Bart

Bart 同学表示躺枪。

类似的,倒数第二用 -2 表示,倒数第三用 -3 表示,倒数第四用 -4 表示:

>>> print L[-2]
Lisa
>>> print L[-3]
Adam
>>> print L[-4]
Traceback (most recent call last):
  File "", line 1, in 
IndexError: list index out of range

L[-4] 报错了,因为倒数第四不存在,一共只有 3 个元素。

使用倒序索引时,也要注意不要越界

Python 之添加新元素

现在,班里有 3 名同学:

>>> L = ['Adam', 'Lisa', 'Bart']

今天,班里转来一名新同学 Paul,如何把新同学添加到现有的 list 中呢?

第一个办法是用 list 的 append() 方法,把新同学追加到 list 的末尾:

>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.append('Paul')
>>> print L
['Adam', 'Lisa', 'Bart', 'Paul']

**append()**总是把新的元素添加到 list 的尾部。

如果 Paul 同学表示自己总是考满分,要求添加到第一的位置,怎么办?

方法是用 list 的 insert() 方法,它接受两个参数,第一个参数是索引号,第二个参数是待添加的新元素:

>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.insert(0, 'Paul')
>>> print L
['Paul', 'Adam', 'Lisa', 'Bart']

L.insert(0, 'Paul') 的意思是,'Paul'将被添加到索引为 0 的位置上(也就是第一个),而原来索引为 0 的 Adam 同学,以及后面的所有同学,都自动向后移动一位。

Python 从 list 删除元素

Paul 同学刚来几天又要转走了,那么我们怎么把 Paul 从现有的 list 中删除呢?

如果 Paul 同学排在最后一个,我们可以用 list 的 pop() 方法删除:

>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> L.pop()
'Paul'
>>> print L
['Adam', 'Lisa', 'Bart']

**pop()**方法总是删掉 list 的最后一个元素,并且它还返回这个元素,所以我们执行 L.pop() 后,会打印出 'Paul'。

如果 Paul 同学不是排在最后一个怎么办?比如 Paul 同学排在第三:

>>> L = ['Adam', 'Lisa', 'Paul', 'Bart']

要把 Paul 踢出 list,我们就必须先定位 Paul 的位置。由于 Paul 的索引是 2,因此,用 pop(2) 把 Paul 删掉:

>>> L.pop(2)
'Paul'
>>> print L
['Adam', 'Lisa', 'Bart']

Python 中替换元素

假设现在班里仍然是 3 名同学:

>>> L = ['Adam', 'Lisa', 'Bart']

现在,Bart 同学要转学走了,碰巧来了一个 Paul 同学,要更新班级成员名单,我们可以先把 Bart 删掉,再把 Paul 添加进来。

另一个办法是直接用 Paul 把 Bart 给替换掉:

>>> L[2] = 'Paul'
>>> print L
L = ['Adam', 'Lisa', 'Paul']

对 list 中的某一个索引赋值,就可以直接用新的元素替换掉原来的元素,list 包含的元素个数保持不变。

由于 Bart 还可以用 -1 做索引,因此,下面的代码也可以完成同样的替换工作:

>>> L[-1] = 'Paul'

Python 之创建 tuple

tuple 是另一种有序的列表,中文翻译为“ 元组 ”。tuple 和 list 非常类似,但是,tuple 一旦创建完毕,就不能修改了。

同样是表示班里同学的名称,用 tuple 表示如下:

>>> t = ('Adam', 'Lisa', 'Bart')

创建 tuple 和创建 list 唯一不同之处是用 ( ) 替代了 [ ]

现在,这个 t 就不能改变了,tuple 没有 append()方法,也没有 insert()和 pop()方法。所以,新同学没法直接往 tuple 中添加,老同学想退出 tuple 也不行。

获取 tuple 元素的方式和 list 是一模一样的,我们可以正常使用 t[0],t[-1]等索引方式访问元素,但是不能赋值成别的元素,不信可以试试:

>>> t[0] = 'Paul'
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'tuple' object does not support item assignment

Python 之创建单元素 tuple

tuple 和 list 一样,可以包含 0 个、1 个和任意多个元素。

包含多个元素的 tuple,前面我们已经创建过了。

包含 0 个元素的 tuple,也就是空 tuple,直接用 ()表示:

>>> t = ()
>>> print t
()

创建包含 1 个元素的 tuple 呢?来试试:

>>> t = (1)
>>> print t
1

好像哪里不对!t 不是 tuple ,而是整数 1。为什么呢?

因为 () 既可以表示 tuple,又可以作为括号表示运算时的优先级,结果 (1) 被 Python 解释器计算出结果 1,导致我们得到的不是 tuple,而是整数 1。

正是因为用()定义单元素的 tuple 有歧义,所以 Python 规定,单元素 tuple 要多加一个逗号“,”,这样就避免了歧义:

>>> t = (1,)
>>> print t
(1,)

Python 在打印单元素 tuple 时,也自动添加了一个“,”,为了更明确地告诉你这是一个 tuple。

多元素 tuple 加不加这个额外的“,”效果是一样的:

>>> t = (1, 2, 3,)
>>> print t
(1, 2, 3)

Python 之“可变”的 tuple

前面我们看到了 tuple 一旦创建就不能修改。现在,我们来看一个“可变”的 tuple:

>>> t = ('a', 'b', ['A', 'B'])

注意到 t 有 3 个元素:'a','b'和一个 list:['A', 'B']。list 作为一个整体是 tuple 的第 3 个元素。list 对象可以通过 t[2] 拿到:

>>> L = t[2]

然后,我们把 list 的两个元素改一改:

>>> L[0] = 'X'
>>> L[1] = 'Y'

再看看 tuple 的内容:

>>> print t
('a', 'b', ['X', 'Y'])

不是说 tuple 一旦定义后就不可变了吗?怎么现在又变了?

别急,我们先看看定义的时候 tuple 包含的 3 个元素:

当我们把 list 的元素**'A'和'B'修改为'X'和'Y'**后,tuple 变为:

表面上看,tuple 的元素确实变了,但其实变的不是 tuple 的元素,而是 list 的元素。

tuple 一开始指向的 list 并没有改成别的 list,所以,tuple 所谓的**“不变”是说,tuple 的每个元素,指向永远不变。即指向'a',就不能改成指向'b'**,指向一个 list,就不能改成指向其他对象,但指向的这个 list 本身是可变的!

理解了**“指向不变”**后,要创建一个内容也不变的 tuple 怎么做?那就必须保证 tuple 的每一个元素本身也不能变。

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    535 引用 • 672 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...