Python学习笔记2:类型与运算

第4章 介绍Python对象类型

Python程序可以分解为模块,语句,表达式,对象:

  1. 程序由模块构成。
  2. 模块包含语句。
  3. 语句包含表达式。
  4. 表达式建立并处理对象。

4.1 为什么使用内置类型

Python内置了强大的对象类型作为语言的组成部分,除非你有内置类型无法提供的特殊对象要处理,才需要自己手动实现。

注意,最好总是使用内置对象而不是使用自己的实现!原因如下:

  • 内置对象使程序更容易编写
  • 即便自己动手实现对象,建议在内置类型的基础之上进行扩展
  • 内置对象往往比自实现的数据结构更有效率
  • 内置对象是语言标准的一部分

4.1.1 Python的核心数据类型

  • 数字:1234, 3.1415, 3+4j, Decimal, Fraction
  • 字符串:‘spam’, b’a\xolc’
  • 列表
  • 字典
  • 元组
  • 文件
  • 集合
  • 其他类型:类型、None、布尔型
  • 编程单元类型:函数、模块、类
  • 与实现相关的类型:编译的代码堆栈跟踪

Python中处理的所有东西都是对象!

Python是动态类型的(它自动地跟踪你的类型而不是要求事先进行声明),但它也是强类型语言(你只能对一个对象进行适合该类型的有效的操作)。例如,字符串只能使用字符串类型的方法,列表只能使用列表类型的方法。

4.2 数字

Python的核心对象包括常规的数字类型:

  • 整数
  • 浮点数
  • 有虚部的复数
  • 固定精度的十进制数
  • 带分子和分母的有理分数
  • 集合
  • 布尔值
  • 第三方开源扩展甚至包含 矩阵 和 向量

4.3 字符串

字符串用来记录文本信息。字符串是包含一个或多个字符的序列。
序列是包含其他对象的有序集合。序列中的元素具有从左向右的顺序,其他类型的序列还包括列表和元组。

4.3.1 序列的操作

Python中的变量不需要提前声明,当给一个变量赋值的时候就创建了它。
在使用变量之前必须对其进行赋值。

索引

作为序列,字符串中的元素也具有位置顺序。在Python中,索引是按照从左到右的顺序从0开始编码的。第一个元素的索引为0,第二个元素的索引为1,依此递增。

>>> S = 'spam'
>>> S
'spam'
>>> len(S)
4
>>> S[0]
's'
>>> S[1]
'p'
>>> S[:]
'spam'

Python中支持序列的反向索引,即最后一个元素开始向前索引。

>>> S[-1]
'm'
>>> S[-2]
'a'
>>> S[::-1]
'maps'

负的索引号会简单地与字符串的长度相加,因此以下两个操作是等效的:

>>> S[-1]
'm'
>>> S[len(S)-1]
'm'
分片

除了简单地从元素位置进行索引,序列还支持分片(slice)操作。这是一种能够一次性地提取序列中的部分元素或全部元素的操作。

>>> S[0:2]
'sp'
>>> S[:2]
'sp'
>>> S[1:3]
'pa'
>>> S[:-1]
'spa'
>>> S[1:-1]
'pa'
>>> S[:]
'spam'

利用负值的步进参数,Python还支持反向分片操作:

>>> S[::-1]
'maps'
加号进行序列拼接,星号(乘号)进行重复
>>> S
'spam'
>>> S+'xyz'
'spamxyz'
>>> S
'spam'
>>> S*8
'spamspamspamspamspamspamspamspam'

4.3.2 不可变性

字符串具有不可变性,即在创建之后不能就地改变。要改变一个字符串的值,只能重新生成的一个新的字符串。
也就是说,不能通过对字符串中某一位置的元素进行赋值来改变字符串,但可以通过重新创建一个新的字符串并以同一个变量名对其进行赋值。例如:

>>> S
'spam'
>>> S[0] = 'z'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> S = 'z' + S[1:]
>>> S
'zpam'

注意:在Python中的每个对象都分为 不可变 或者 可变
在核心类型中,数字、字符串和元组是不可变的;列表和字典不是这样(它们可以完全自由地改变)。

4.3.3 类型特定的方法

除了一般的序列操作,字符串还有一些独有的操作作为方法存在。

注意:尽管序列操作是通用的,但方法不通用(虽然某些类型具有相同的方法名,字符串的方法只能用于字符串)。
可作用域多种类型的通用操作都是以内置函数或表达式的形式出现的,例如,len(X)X[0],但类型特定的操作是以方法调用的形式出现的,例如,aString.upper()

4.3.4 需求帮助

对于某种类型的更多细节,你可以调用内置的dir函数查看,它将返回一个包含了对象的所有属性的列表。

>>> dir(S)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

使用内置的help函数查询特定对象或类型是做什么的。

>>> help(S.replace)
Help on built-in function replace:

replace(...) method of builtins.str instance
    S.replace(old, new[, count]) -> str

    Return a copy of S with all occurrences of substring
    old replaced by new.  If the optional argument count is
    given, only the first count occurrences are replaced.
(END)

4.3.5 编写字符串的其他方法

Python允许字符串包括在单引号或双引号中。

Python还允许在三个引号(单引号或双引号)中包括多行字符串常量。当采用这种形式时,所有行都合并在一起,并在每一行的末尾增加换行符。

在 Python 3 中,str字符串类型都支持Unicode,并且bytes类型表示原始字节字符串。

在 Python 2.6 中,Unicode是一种单独的类型,str类型处理8位字符串和二进制数据。

4.4 列表

列表是一个由一个或多个任意类型的对象组成的有序集合,它没有固定大小。

列表是可变的。

4.4.1 序列操作

由于列表是序列的一种,列表支持所有的序列操作,包括:

  • 索引
  • 分片
>>> L = [123, 'spam', 1.23]
>>> len(L)
3
>>> L[0]
123
>>> L[:-1]
[123, 'spam']
>>> L + [4, 5, 6]
[123, 'spam', 1.23, 4, 5, 6]
>>> L
[123, 'spam', 1.23]
>>> L*2
[123, 'spam', 1.23, 123, 'spam', 1.23]

4.4.2 类型的特定操作

列表是可变的,大多数列表的方法都会就地改变列表对象,而不是创建一个新的列表:

>>> M = ['aa', 'bb', 'cc']
>>> M.sort()
>>> M
['aa', 'bb', 'cc']
>>> M.reverse()
>>> M
['cc', 'bb', 'aa']

4.4.3 边界检查

Python不允许引用不存在的元素,超出列表索引范围会导致错误:

>>> M
['cc', 'bb', 'aa']
>>> M[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> M[4] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>>

4.4.4 嵌套

Python核心数据类型支持以任意组合进行嵌套(一个列表、元组或者字典可以包含多个不同类型的对象),并可以进行多个层级的嵌套。这一特性可用于实现矩阵。

>>> M = [[1,2,3],[4,5,6],[7,8,9]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> M[1][0]
4
>>> M[0][0]
1
>>>

4.4.5 列表解析表达式(list comprehensive expression)

列表解析表达式(list comprehensive expression)是一种通过对序列中的每一项运行一个表达式来创建一个新列表的方法。

>>> li = [row[1] for row in M]
>>> li
[2, 5, 8]
>>> li = [row[1]+1 for row in M]
>>> li
[3, 6, 9]
>>> li = [row[1] for row in M if row[1] % 2 == 0]
>>> li
[2, 8]
>>> li = [M[i][i] for i in [0,1,2]]
>>> li
[1, 5, 9]
>>> li = [i for i in range(10)]
>>> li
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4.5 字典

Python中的字典是一种映射。
映射是一种通过键而不是相对位置(如序列)来存储对象的集合。
映射中的元素不存在可靠的从左至右的位置顺序关系。
字典具有可变性,可以就地改变。
作为映射,字典只支持通过键获取元素。

4.5.1 映射操作

字典编写在大括号中,并包含一系列的“键:值”对。

>>> D = {
   'food':'Spam', 'quantity':4, 'color':'pink'}
>>> D
{
   'food': 'Spam', 'quantity': 4, 'color': 'pink'}
>>> D['food']
'Spam'
>>> D['quantity'] + 1
5
>>> D['quantity'] = 6
>>> D['quantity']
6
>>>

4.5.2 嵌套

字典同样支持元素的嵌套:

>>> rec = {
   'name':{
   'first':'Peter', 'last':'Parker'}, 'job':['dev','mgr'],'age':40.5}
>>> rec['name']
{
   'first': 'Peter', 'last': 'Parker'}
>>> rec['name']['first']
'Peter'
>>> rec['job']
['dev', 'mgr']
>>> rec['job'].append('ceo')
>>> rec
{
   'name': {
   'first': 'Peter', 'last': 'Parker'}, 'job': ['dev', 'mgr', 'ceo'], 'age': 40.5}
>>>

4.5.3 键的排序:for循环

字典作为映射,其中的元素不存在可靠的从左至右的位置顺序关系。但如果需要强调某种顺序,可以提取一个字典键的列表,对其中的键进行排序,然后依次输出字典中的值:

>>> D = {
   'a':1, 'b':2, 'c':3}
>>> Ks = list(D.keys())
>>> Ks.sort()
>>> Ks
['a', 'b', 'c']
>>> for key in Ks:
...     print(key, '->', D[key])
...
a -> 1
b -> 2
c -> 3

在较新的Python版本中,也可以使用内置函数sorted直接对字典的键进行排序:

>>> for key in sorted(D):
...     print(key, '->', D[key])
...
a -> 1
b -> 2
c -> 3

4.6 元组

元组类型基本上就像是一个不可变的列表。

从语法上讲,它们编写在圆括号中,它支持任意类型、任意嵌套以及常见的序列操作:

>>> T = (1, 2, 3, 4)
>>> len(T)
4
>>> T + (5, 6)
(1, 2, 3, 4, 5, 6)
>>> T[0]
1
>>>

4.6.1 为什么要用元组

如果在程序中以列表的形式传递一个对象的集合,它可能在任何地方改变;如果使用元组,则不能。也就是说,元组提供了一种完整性的约束。

4.7 文件

文件对象是Python代码对电脑上外部文件的主要接口。

虽然文件是核心类型,但没有常量(literal,也有翻译为“字面量”)语法来创建文件对象。需要使用open函数来创建。

字面量(iteral)在本书中被翻译为常量,但其他书中也有翻译为字面量的,个人觉得“字面量”更贴切,也不容易与其他语言中使用关键字const进行声明的量混淆。

>>> f = open('test.py', 'r')
>>> f.read()
"a = 'dead'\nb = 'parrot'\nc = 'sketch'\nprint(a, b, c)\n"

4.7.1 其他文件类工具

open函数能够实现在Python中的大多数文件处理场景。但对于更高级的任务,Python还提供了额外的类文件工具:

  • 管道
  • FIFO队列
  • 套接字
  • 通过键访问文件
  • 对象持久
  • 基于描述符的文件(Descriptor file)
  • 关系数据库接口
  • 面向对象数据库接口

4.8 其他核心类型

4.8.1 集合

集合是不可变的对象的无序集合,它有点像是没有值的字典的键。
集合可以通过调用内置set函数创建,或者使用Python 3.0中新的集合常量(literal,也有翻译为“字面量”)语法和表达式创建。
集合支持一般的数学集合操作(交集、并集、补集)。

字面量(iteral)在本书中被翻译为常量,但其他书中也有翻译为字面量的,个人觉得“字面量”更贴切,也不容易与其他语言中使用关键字const进行声明的量混淆。

>>> X = set('spam')
>>> Y = {
   'h', 'a', 'm'}
>>> X
{
   's', 'a', 'p', 'm'}
>>> Y
{
   'a', 'm', 'h'}
>>> X,Y
({
   's', 'a', 'p', 'm'}, {
   'a', 'm', 'h'})
>>> X & Y        # X和Y的交集
{
   'a', 'm'}
>>> X | Y        # X和Y的并集
{
   's', 'a', 'p', 'm', 'h'}
>>> X - Y        # Y在X中的补集
{
   's', 'p'}
>>> {
   x ** 2 for x in [1, 2, 3, 4]}      # 列表推导式创建集合
{
   16, 1, 9, 4}
>>>

4.8.2 Decimal 十进制数(固定精度浮点数)

Decimal对象用来表示十进制数,也称为固定精度浮点数。

>>> 1 / 3    # 浮点数
0.3333333333333333
>>> (2/3) + (1/2)
1.1666666666666665
>>>
>>> import decimal
>>> d = decimal.Decimal('3.1415926')     # 固定精度浮点数
>>> d
Decimal('3.1415926')
>>> d + 1
Decimal('4.1415926')

4.8.3 Fraction 分数(有一个分子和一个分母的有理数)

>>> from fractions import Fraction
>>> f = Fraction(2, 3)
>>> f
Fraction(2, 3)
>>> f + 1
Fraction(5, 3)
>>> f + Fraction(1, 2)
Fraction(7, 6)
>>>

4.8.4 布尔值

布尔值是预定义的True和False对象,实际上是定制后以逻辑结果显示的整数1和0。

>>> 1 > 2
False
>>> 1 < 2
True
>>> 1 > 2, 1 < 2
(False, True)
>>> bool('Spam')
True
>>> X = None
>>> bool(X)
False
>>> L = [None] * 100
>>> bool(L)
True
>>>

4.8.5 如何破坏代码灵活性

内置函数type返回对象的类型(类)。

>>> type(L)
<class 'list'>
>>> type(type(L))
<class 'type'>

内置函数type允许编写代码来检查它所处理的对象类型(类)。

>>> type(L) == type([])
True
>>> type(L) == list
True

类似的还可以使用isinstance函数来判断某个对象是否是某个类的实例:

>>> isinstance(L, list)
True
>>>

Python 3.0中类型已经完全和类结合起来了。

4.8.6 用户定义的类

假如你希望有一个对象类型能对职员进行建模,尽管Python没有内置这样的核心类型(类),用户也可以定义符合自己需求的类。


第5章 数字

5.1 Python的数字类型

Python数字类型的完整工具包括:

  • 整数和浮点数
  • 复数
  • 固定精度的十进制数
  • 有理分数
  • 集合
  • 布尔类型
  • 无穷的整数精度
  • 各种数字内置函数和模块

5.1.1 数字常量(literal,字面量)

在基本类型中,Python提供了:整数和浮点数。
Python允许我们使用十六进制、八进制和二进制字面量来表示整数。
Python还提供一个复数类型。
Python允许整数具有无穷的精度(只要内存空间允许,它可以增长成任意位数的数字)。

字面量(iteral)在本书中被翻译为常量,但其他书中也有翻译为字面量的,个人觉得“字面量”更贴切,也不容易与其他语言中使用关键字const进行声明的量混淆。

关于数字类型:

  • 整数和浮点数字面量
    • 整数不带小数点。
    • 浮点数带一个小数点,也可以加上一个科学计数标志e或者E
  • 在Python 3.0中,整数和长整数已经合二为一,只有整数这一种。
  • 整数可以编写为十进制、十六进制、八进制、二进制形式。
  • 复数:Python的复数常量写成实部+虚部的写法,虚部以j或者J结尾。也可以通过内置函数complex来创建复数。

5.1.2 内置数学工具和扩展

Python提供了一系列处理数字对象的工具:

  • 表达式操作符:+、-、*、/ 、>> 、**、&等。
  • 内置数学函数:powabsroundinthexbin等。
  • 公用模块:randommath等。

5.1.3 Python表达式操作符

表达式是处理数字的最基本工具。当一个数字(或其他对象)与操作符相结合时,Python执行时将计算得到一个值。

混合操作时将遵循操作符的优先级
混合类型自动提升

在混合类型的表达式中,Python将被操作的对象转换成其中最复杂的操作对象的类型,然后再对相同类型的操作对象进行数学运算。

在Python中,整数比浮点数简单,浮点数比复数简单。所以当整数与浮点数运算时,整数将被自动转换为浮点数,以此类推。

>>> type(4)
<class 'int'>
>>> type(3.14)
<class 'float'>
>>> type(4 + 3.14)
<class 'float'>

可以通过手动调用内置函数来强制类型转换:

>>> int(3.1415)
3
>>> float(3)
3.0

在Python 3.0中,非数字混合类型是不允许的,会引发异常。

>>> 'string' + 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
运算符重载

Python的操作符可以通过Python的类或C扩展类型被重载(即实现),让它也能工作与你所创建的对象中。例如,用户自定义的类也可以使用+表达式进行加法或连接等。

其次,Python也会自动重载某些操作符,能够根据所处理的内置对象的类型而执行不同的操作。例如,+操作符应用于数字时是在做加法,而应用于字符串是连接字符串。

5.2 数字的实际应用

5.2.1 变量和基本的表达式

在Python中:

  • 变量在它第一次赋值时创建。
  • 变量在表达式中使用前必须已被赋值。
  • 变量像对象一样不需要在一开始进行声明。
  • 在表达式中使用变量,表达式的值将变为变量操作结果的值。

5.2.2 数字显示格式

5.2.3 比较:一般的和连续的

>>> 1 < 2
True
>>> 1 < 2 < 3
True
>>> 1 < 2 and 2 < 3
True
>>>

5.2.3 除法:传统除法、Floor除法和真除法

Python 3.0中有2种类型的除法,有2种不同的除法操作符。

  • 传统除法和真除法: X / Y,不管操作数的类型,都返回包含任何余数的一个浮点数结果。
  • Floor除法:X // Y,总会截断余数并向下取整,相当于对结果调用了math.floor函数。如果有任何一个操作数是浮点类型,则返回一个浮点数,否则,结果是一个整数。
>>> 5 / 2
2.5
>>> 5 / -2
-2.5
>>> 5 // 2
2
>>> 5 // -2
-3
>>>

如果想要单纯的截断丢弃小数部分,可以总是通过math.trunc来得到一个浮点除法结果。

>>> import math
>>> 5 / -2
-2.5
>>> 5 // -2
-3
>>> math.trunc(5/-2)
-2
>>>

5.2.4 整数精度

Python 3.0整数支持无穷的大小(取决于计算机内存)。

5.2.5 复数

复数是Python中的另一个核心对象类型。
Python中,用两个浮点数分别表示一个复数的实部和虚部,并在虚部增加jJ的后缀。

>>> 2 + -3j
(2-3j)
>>> 1j*1J
(-1+0j)
>>> 2+1j*3
(2+3j)
>>> (2
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值