数据类型和变量

整数

和数学上的写法一样。
对于很大的数,允许在数字中间以 _ 分隔。10_000_000_00010000000000 是完全一样的。
Python的整数没有大小限制。

浮点数

对于很大或很小的浮点数,必须用科学计数法表示,把10用e替代。
1.23*109就是 1.23e9 或者是 12.3e80.000012 可以写成 1.2e-5
浮点数运算可能会有四舍五入的误差。整数运算永远精确,包括除法。

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

字符串

转义字符\

r'':默认不转义

r''表示''内部的字符串默认不转义:

  1. >>> print('\\\t\\')
  2. \ \
  3. >>> print(r'\\\t\\')
  4. \\\t\\

'''...''':多行内容

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

  1. # 注意,以下是在python交互模式执行,...是提示符,不是代码的一部分
  2. >>> print('''line1
  3. ... line2
  4. ... line3''')
  5. line1
  6. line2
  7. line3
  1. # 如果写成程序并存为.py文件
  2. print('''line
  3. line2
  4. line3''')

r'''...'''

多行字符串'''...'''还可以在前面加上r使用。

布尔值(and、or、not)

布尔值可以用andornot运算。
and运算是与运算,只有所有都为Trueand运算结果才是True
or运算是或运算,只要其中有一个为Trueor运算结果就是True
not运算是非运算,它是一个单目运算符,把True变成FalseFalse变成True

  1. >>> True and False
  2. False
  3. >>> True or False
  4. True
  5. >>> not True
  6. False

空值:None

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

变量

变量名必须是大小写英文、数字和_的组合,且不能数字开头

常量

通常用全部大写的变量名表示常量。(但只是习惯上的用法,实际还是个变量,非要改变也没法。)

除法

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

    1. >>> 10 / 3
    2. 3.3333333333333335
    3. >>> 9 / 3
    4. 3.0
  • 还有一种除法是//,称为地板除,两个整数的除法仍然是整数:

    1. # 取结果的整数部分
    2. >>> 10 // 3
    3. 3
  • 余数运算,得到两个整数相除的余数。

    1. >>> 10 % 3
    2. 1

字符串和编码

ord(), chr()

ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:

  1. >>> ord('A')
  2. 65
  3. >>> ord('中')
  4. 20013
  5. >>> chr(66)
  6. 'B'
  7. >>> chr(25991)
  8. '文'

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

  1. x = b'ABC' #`bytes`的每个字符都只占用一个字节

encode(), decode()

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

  1. >>> 'ABC'.encode('ascii')
  2. b'ABC'
  3. >>> '中文'.encode('utf-8')
  4. b'\xe4\xb8\xad\xe6\x96\x87'
  5. >>> '中文'.encode('ascii')
  6. Traceback (most recent call last):
  7. File "<stdin>", line 1, in <module>
  8. UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

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

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

如果bytes中包含无法解码的字节,decode()方法会报错。
如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:

  1. >>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
  2. '中'

len()

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

  1. >>> len('ABC')
  2. 3
  3. >>> len('中文')
  4. 2

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

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

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

编码

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

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

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

格式化

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

  1. >>> 'Hello, %s' % 'world'
  2. 'Hello, world'
  3. >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
  4. 'Hi, Michael, you have $1000000.'

%运算符就是用来格式化字符串的。

在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。

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

  1. print('%2d-%02d' % (3, 1)) # 3-01 (%2d 两位整数,不足的默认用空格补充)
  2. # (%02d 两位整数,不足的用0补充)
  3. print('%.2f' % 3.1415926) #3.14 (%.2f保留两位小数)

%2d是将数字按宽度为2,采用右对齐方式输出,若数据位数不到2位,则左边补空格
%02d,和%2d差不多,只不过左边补0
%.2d%02d一样

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

  1. >>> 'growth rate: %d %%' % 7
  2. 'growth rate: 7 %'

format()

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

  1. >>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
  2. 'Hello, 小明, 成绩提升了 17.1%'

f-string

f开头的字符串,字符串如果包含{xxx},就会以对应的变量替换:

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

使用list和tuple

list

  1. >>> classmates = ['Michael', 'Bob', 'Tracy']
  2. >>> len(classmates) # 用len()函数可以获得list元素的个数
  3. >>> classmates[0] # 用索引来访问list中每一个位置的元素,记得索引是从0开始的
  4. # 最后一个元素的索引是len(classmates) - 1
  5. >>> classmates[-1] # 直接获取最后一个元素,类推,倒数第二个为 classmates[-2]

当索引超出范围时,Python会报一个IndexError错误。

切片

切片适用于提取序列的一部分,其中的编号非常重要:第一个索引是包含的第一个元素的编号,但第二个索引是切片后余下的第一个元素的编号,第三个参数是步长。

  1. numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  2. numbers[3:6] # [4, 5, 6]
  3. numbers[-3:-1] # [8, 9] 从列表末尾开始数,可使用负数索引
  4. numbers[-3:0] # []
  5. numbers[-3:] # [8, 9, 10] 如果切片结束于序列末尾,可省略第二个索引
  6. numbers[:3] # [1, 2, 3] 切片始于序列开头,可省略第一个索引
  7. numbers[:] # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 复制整个序列,可将两个索引都省略
  8. # 步长不能为0
  9. numbers[0:10:2] # [1, 3, 5, 7, 9]
  10. numbers[::4] # [1, 5, 9]
  11. # 插入新元素
  12. >>> numbers = [1, 5]
  13. >>> numbers[1:1] = [2, 3, 4]
  14. >>> numbers
  15. [1, 2, 3, 4, 5]

添加和删除

  1. >>> classmates.append('Adam') # 往list中追加元素到末尾
  2. >>> classmates.insert(1, 'Jack') # 把元素插入到指定位置,如索引号为1的位置
  3. >>> classmates.pop() # 删除list末尾的元素
  4. >>> classmates.pop(1) # 删除指定位置的元素,用pop(i),i是索引位置
  5. >>> classmates[1] = 'Sarah' # 直接赋值给对应的索引位置,替换元素
  6. >>> classmates.clear() # 就地清空列表
  7. # 使用 del 语句删除元素,列表长度会减少
  8. >>> names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']
  9. >>> del names[2]
  10. >>> names
  11. ['Alice', 'Beth', 'Dee-Dee', 'Earl']
  12. >>> names[1:4] = [] # 切片替换删除,与del names[1:4]等效
  13. >>> names
  14. ['Alice']

复制

  1. # number1,2,3指向不同的列表
  2. number1 = [1,2,3,4,5]
  3. number2 = number[:] # 切片复制
  4. number3 = list(number1) # list复制

tuple

和list非常类似,但是tuple一旦初始化就不能修改。
获取元素的方法和list是一样,但不能赋值成另外的元素。

  1. >>> x = 1, 2, 3
  2. >>> x
  3. (1, 2, 3)
  4. >>> t = () # 定义一个空的tuple
  5. >>> t = (1,) # 定义一个只有1个元素的tuple,不能写成t = (1)
  6. >>> t
  7. (1,) # Python在显示只有一个元素的tuple时也会加逗号避免歧义。
  8. >>> t = (1, 2)
  9. >>> 3 * (40 + 2)
  10. 126
  11. >>> 3 * (40 + 2,)
  12. (42, 42, 42)
  1. # 可变的tuple
  2. >>> t = ('a', 'b', ['A', 'B'])
  3. >>> t[2][1] = 'X'

条件判断

  1. if <条件判断1>:
  2. <执行1>
  3. elif <条件判断2>:
  4. <执行2>
  5. elif <条件判断3>:
  6. <执行3>
  7. else:
  8. <执行4>

再议 input

input()读取用户的输入,返回的数据类型是str
int()函数来把str转换成整数。
float()函数把str转换成浮点数。

  1. s = input('birth: ')
  2. birth = int(s)
  3. if birth < 2000:
  4. print('00前')
  5. else:
  6. print('00后')

循环

for…in循环

  1. names = ['Michael', 'Bob', 'Tracy']
  2. for name in names:
  3. print(name)
  1. >>> list(range(5)) # range()函数,可以生成一个整数序列
  2. [0, 1, 2, 3, 4] # 再通过list()函数可以转换为list

while循环

只要条件满足,就不断循环,条件不满足时退出循环。

  1. # 例:计算100以内所有奇数之和
  2. sum = 0
  3. n = 99
  4. while n > 0:
  5. sum = sum + n
  6. n = n - 2
  7. print(sum)

break

break语句可以提前退出循环

continue

通过continue语句,跳过当前的这次循环,直接开始下一次循环。

使用dict和set

dict(相当于js的对象)

  1. >>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
  2. >>> d['Michael'] # 95
  3. >>> d['Adam'] = 67
  4. >>> d['Adam'] # 67

通过in判断key是否存在

  1. >>> 'Thomas' in d # False

get(key)

通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:

  1. >>> d.get('Thomas') # 返回None的时候Python的交互环境不显示结果
  2. >>> d.get('Thomas', -1) # -1

pop(key)

要删除一个key,用pop(key)方法,对应的value也会从dict中删除:

  1. >>> d.pop('Bob') # 75
  2. >>> d # {'Michael': 95, 'Tracy': 85}

删除字典元素

  1. dict = {'Name': 'W3CSchool', 'Age': 7, 'Class': 'First'}
  2. del dict['Name'] # 删除键 'Name'
  3. dict.clear() # 删除字典
  4. del dict # 删除字典

set

set和dict类似,也是一组key的集合,但不存储value。key不能重复,所以,在set中没有重复的key。
不可放入可变对象。

  1. >>> s = set([1, 2, 3]) # {1, 2, 3}
  2. >>> s = set([1, 1, 2, 2, 3, 3]) # {1, 2, 3} 重复元素在set中自动被过滤

add()、remove()

  1. >>> s.add(4) # {1, 2, 3, 4} 通过add(key)方法添加元素到set中,重复添加不会有效果
  2. >>> s.remove(4) # {1, 2, 3} 通过remove(key)方法可以删除元素

交集 &、并集 |

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

  1. >>> s1 = set([1, 2, 3])
  2. >>> s2 = set([2, 3, 4])
  3. >>> s1 & s2 # {2, 3} 交集
  4. >>> s1 | s2 # {1, 2, 3, 4} 并集

取值

list() 可以将集合转换为列表。

  1. s = set([1,2,3])
  2. print(s[0]) # TypeError: 'set' object does not support indexing
  3. print(list(s)[0]) # 1

再议不可变对象

对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。