Python基础:02.数据类型与变量
一、数据类型
1. 标准数据类型
Python3 中有六个标准的数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
按照数据类型是否可变分为:
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)
为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象
按照数据类型是否属于sequence(序列):
序列 :string、list 和 tuple String(字符串)、List(列表)、Tuple(元组)
非序列 : Number(数字)、Dictionary(字典)、Set(集合)
2. 其他数据类型
空值
空值是Python里一个特殊的数据类型,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值,None也是不可变的
布尔型
Ture:非0值
False: ' '
、" "
、''' '''
、""" """
、0
、( )
、[ ]
、{ }
、None
、0.0
、0L
、0.0+0.0j
二、变量与对象
Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
1. 理解动态语言
Python 是一门动态语言,在python中,变量就是变量,它没有类型,对象才有类型,我们所说的“类型”是变量所指的内存中对象的类型。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量。这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错
下面的代码中,一开始把数字赋给了变量a,后面又把字符串赋给了a
1 |
|
‘abc’
2. 变量命名
变量名必须是大小写英文、数字和_的组合,且不能用数字开头。
遇到多个单词组合命名常使用两种命名方式:(一个文件中尽量只使用一种命名方式)
- 驼峰式:即前一个单词小写,后一个单词首字母大写。如:stuName
- 下划线式:单词之间用下划线连接。如:stu_name
需要注意:变量命名不要和python保留字相同
1 |
|
[‘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’]
3. 多个变量赋值
Python允许同时为多个变量赋相同的值。
1 |
|
也允许同时为多个变量赋不同的值,其本质为:元组打包和解包。后面会学
- temp = 2,3 元组打包
- x,y = temp 序列解包
1 |
|
2 3
4. 常量
所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量。但事实上PI仍然是一个变量,Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量PI的值,也没人能拦住你
1 |
|
3.141592653589793
5. 变量类型转换
有时候,我们需要对数据内置的类型进行转换,数据类型的转换,只需要将数据类型作为函数名即可。
以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。
1 |
|
1
1.0
123.0
1
1
True
False
需要注意的是不能将非数字的字符型转为整型、浮点型
1 |
|
字符串内容为浮点型要转换为整型,需要先用浮点型转换,再转换为整型
1 |
|
6. 不可变和可变类型
对不可变和可变类型对象的理解
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了
7. 变量与对象的联系
python中,对象才有类型,变量是没有类型的。变量仅仅是对象的引用(指针)
可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量。下面这段代码[1,2,3]
是list类型,'python'
是string类型,变量a没有类型
1 |
|
理解变量和对象的关系在计算机内存中非常重要。
当我们写:a = ‘ABC’时,Python解释器干了两件事情:
- 在内存中创建了一个’ABC’的字符串;
- 在内存中创建了一个名为a的变量,并把它指向’ABC’
下面这段代码,对应着变量和对象的关系
1 |
|
相对应的,如果只是改变a本来指向的对象,b也还是指向它。下面的代码输出[1, 2, 3, 4]
1 |
|
三、数字
1. 数字类型
- 整数:Python3 里只有一种整数类型 int,表示为长整型
- 浮点数:浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的。如 1.23、3E-2
- 布尔型:True、False
- 复数
1 |
|
<class ‘int’>
<class ‘float’>
<class ‘bool’>
复数
复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。 python 不支持复数转换为整数或浮点数
复数常见的用法有:
- a为复数,a.real为实数部分,a.imag虚数部分的实数
- complex(x) 将x转换到一个复数,实数部分为 x,虚数部分为 0
- complex(x, y) 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y,其中x 和 y 是数字表达式
1 |
|
<class ‘complex’>
<class ‘complex’>
3.0
4.0
2. 常见数值运算函数
常见数值运算函数见下表。其中abs(x)
、round(x)
是python内置函数,其他的函数需要调用math模块
1 |
|
1.2
4
4.57
1 |
|
5
2.718281828459045
10.0
4
1.0
2.0
2.0
(0.5, 4.0)
9.0
3.0
3
3
其中有关round()函数的注意点:
- round函数在取整浮点数时,遵循的原则是:
4舍6入5看齐,奇进偶不进
- 待进位是5的时候,还需要看待进位的前一位,前一位是奇数才进一,偶数不进。如果还有小数点第二位或更多位,则不管奇偶,大于0.5都是进位的
- 但到了保留小数点后多位时,又会出问题,这和python自身的二进制浮点数精度有关,所以精度要求高的时候不要用round函数,用decimal模块,用到时候再学
1 |
|
3
4
4
4
5
4.57
4.67
3. 数学常数
math模块中有e和pi这两个数学常数
1 |
|
2.718281828459045
3.141592653589793
4. 三角函数
pi涉及到三角函数的函数调用,用到查看即可,使用频率较低
1 |
|
0.5000000000000001
5. 科学计数法
科学计数法:在e的前后加上主数字和10的次幂。注意此处的e与自然底数无关,不要混淆
1 |
|
15200.0
0.0152
1523.0
四、运算符
python有多种运算符:
算术运算符、比较运算符、赋值运算符、位运算符、逻辑运算符、成员运算符、身份运算符等
1. 算术运算符
/
除 //
取整 %
取余 这三个切忌弄混
**
幂
它们的运算顺序与数学相同,括号,幂运算,乘除,加减
1 |
|
42
22
320
3.2
2
3
8
补充:函数divmod()
以元组形式返回除法的商和余数
1 |
|
(3, 1)
//
取整结果不一定是整型,这与分母分子的数据类型有关,不同类型的数混合运算时会将整数转换为浮点数
//
取整是向下取接近商的整数,负数运算时容易搞错
1 |
|
3.0
3
-3
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(包括除法),而浮点数运算则可能会有四舍五入的误差
之所以整数的除法运算永远是精确的,因为其包括两种,一种是/
,一种是//
,**/
除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数**,还有一种除法是//
,两个整数的取整自然是整数,因此这两种除法都是精确的
2. 比较运算符
==等于 != 不等于 >大于 <小于 >=大于等于 <=小于等于
1 |
|
no
3. 赋值运算符
赋值运算符:=
增量运算符:如+=
加法赋值运算符 b+=a
等效于 b=a+b
,其他的还有-=
*=
/=
**=
1 |
|
51
Python中没有++
和--
的操作!
python中的数字类型是不可变数据,也就是数字类型数据在内存中不会发生改变,当变量值发生改变时,会新申请一块内存赋值为新值,然后将变量指向新的内存地址a = 10; a += 1
两次id(a)是不同的
+=
是改变变量,相当于重新生成一个变量,把操作后的结果赋予这个新生成的变量++
是改变了对象本身,而不是变量本身,即改变数据地址所指向的内存中的内容,python限制了这样的做法
4. 位运算符
按位运算:与& 或| 非~ 异或^ 左移<< 右移>>
1 |
|
12
进制
上面涉及到了位运算符的知识点,补充下python的进制问题
- Python默认变量为十进制,不要对变量进行二进制赋值
- 2 进制是以
0b
开头;8 进制是以0o
开头的;16 进制是以0x
开头的,给变量赋值为这些进制前,需要加上这些开头的符号 - 但给变量赋值为这几种进制,python默认输出仍然是十进制。因此需要以其他进制输出,还要用**bin(),oct(),hex()**这三个函数,对应二、八、十六进制
1 |
|
60
0b111100
5. 逻辑运算符
逻辑的与或非:and/or/not。注意逻辑运算符跟位运算符与或非是不同的
- and :从左到右计算表达式,若存在假,返回第一个假值,若所有值均为真,则返回最后一个值
- or :从左到有计算表达式,若存在真,返回第一个真值,若所有值均为假,则返回最后一个值
- not :如果表达式为 True,返回 False 。如果表达式为 False,它返回 True
- 优先级:not > and > or
1 |
|
666
0
1 |
|
0
60
1 |
|
False
True
6. 成员运算符
in,表示在指定的序列中
not in ,表示不在指定的序列中
1 |
|
True
1 |
|
False
7. 身份运算符
is 判断两个标识符是否引用自同一个对象
is not 判断两个标识符是否不是引用自一个对象
is和==是有区别的,is用于判断两个变量是否为同一个对象,后者用于判断引用变量的值是否相等
1 |
|
140703924103568
140703924103568
a和b有相同的标识
补充一个额外知识点:
在交互式环境中,编译器会有一个小整数池的概念,会把[-5,256]间的整数预先创建好。在这个区间内的整数对象分配了相同的内存地址,超过这个范围的时候,地址就会不同
还会有部分仅包含数字、字母和下划线的字面常量字符串也会被驻留,即分配同一内存空间,用到再说
1 |
|
True
140703924103024
140703924103024
False
1813601033264
1813601033392
False
1813601031472
1813601032944
True
8.运算优先级
五、字符串
字符串是以单引号''
或双引号""
括起来的任意文本。''
或""
本身只是一种表示方式,不是字符串的一部分。字符串'abc'
只有a,b,c这3个字符
Python没有单独的字符类型,一个字符就是长度为 1 的字符串
如果'
本身也是一个字符,那就可以用""
括起来。比如"I'm OK"
包含的字符是I,’,m,空格,O,K这6个字符
在Python3中,所有的字符串都是Unicode字符串
1 |
|
I’m ok
1. 转义字符
如果字符串内部既包含'
又包含"
怎么办?可以用转义字符\
来标识。\'
表示单引号 \"
表示双引号
下表展示了python的转义字符(ESC, escape character)
1 |
|
I’m “ok”
使用r/R表示原始字符串,不会发生转义。r是指raw,原生的
1 |
|
this is a line with \n
如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用''' '''
的格式表示多行内容
并且,''' '''
还是多行注释,python解释器会自动识别
1 |
|
hello world
hello wayu
hello python
2. 字符串运算符
python内置了很多字符串的运算符
1 |
|
helloworld
hello world
hello hello hello
True
注意字符串不能减除
1 |
|
TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’
3. 字符串占位(字符串格式化)
3.1 第一种占位操作 '%d' % ()
第一种占位操作是用的最早的,用%
的格式先在字符串中占位,后面添加小括号指向变量(如果只有一个占位,括号可以省略),中间用%
连接
浮点型的小数位和C语言中类似,格式为%a.bf ,其中a表示显示的最小总宽度,b表示保留几位小数
如果不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串
下表为常用的字符串格式化操作符:
补充:%i 十进制整数
1 |
|
hello wanyu 1 2.00
3.2 第二种占位操作 str.format()
在写字符串时,可以先用{}
占位,再用format()
方法传入值,括号中的参数需要用逗号隔开。默认传入顺序是从前向后,注意format是字符串的方法,所以应该结构是' '.format()
。这种方式不用再去判断使用传入字符串类型是%s,还是 %d
大多数的 Python 代码仍然使用%
操作符。但是这种旧式的格式化最终会被移除, 应该更多的使用 str.format()
1 |
|
hello python 123 !
hello world !
有关占位顺序
如果想改变传入顺序,可以在{ }
用从0开始的数字代表先后顺序
也可以先在{ }
中放入变量,再在format()方法中直接指定变量值
1 |
|
! python hello
hello python !
有关占位长度和小数有效数字
在{ }
中放入a:b.cf
表示这个位置的可选项多了新的要求,即占b个位(b省略则是全部输出),保留c位小数,其中f还可以替换为d等转义字符中的字母,a仍然可以放表示顺序的数字,或者关键字
1 |
|
常量 PI 的值近似为 3.142,常量 e 的值近似为 2.72
字典传入字符串
如果有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时最好通过变量名来访问,而非使用位置。最简单的就是传入一个字典, 然后使用方括号[]
来访问键值,在{}
中依然可以放入数字与后面format中的字典顺序形成对应关系
1 |
|
Runoob: 2; Google: 1; Taobao: 6
也可以通过在format中的变量前使用**
来实现相同的功能,用到再深入了解
1 |
|
Runoob: 2; Google: 1; Taobao: 3
{ }
里可以放入下面的符号用于在格式化某个值之前对其进行转化,用到再深入了解
!a
(使用 ascii())!s
(使用 str())!r
(使用 repr())
3.3 第三种占位操作f ' {} '
f-string 是 python3.6 之后版本添加的。它以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去。
也可以理解为这种方法就是把第二种的.format() 替换为了 f
这种方式也不用再去判断使用 %s,还是 %d
1 |
|
Hello Runoob
3
4. 字符串内建函数&方法
要区分函数和方法的使用
4.1 常用函数
字符串的函数不是太多,主要以方法为主。常用的函数有以下几个:
- len(str)返回字符串长度
- max(str)返回字符串 str 中最大的字母
- min(str)返回字符串 str 中最小的字母
1 |
|
5
o
e
4.2 字符串大小写
- 方法upper()将字符串全部转化为大写
- 方法lower()将字符串全部转化为小写
- 方法capitalize()将字符串首字母转化为大写
- 方法title()返回”标题化”的字符串,就是说所有单词都是以大写开始,其余字母均为小写
- 方法swapcase()将字符串中大写转换为小写,小写转换为大写
1 |
|
HELLO PYTHON
hello python
Hello python
Hello Python
JAVA
4.3 字符串的切分
字符串是不可变对象! 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。这些方法会创建新的对象并返回,保证了不可变对象本身永远是不可变
- 字符串也可以用切片操作符操作,操作结果仍是字符串
- 方法split()可以将字符串进行切分成一个列表,注意返回值是列表,切分完之后需要赋给一个新的变量,否则原变量是不变的,也体现了字符串是不可变对象
1 |
|
o w
[‘1’, ‘2’, ‘3’, ‘4’, ‘5’]
1 2 3 4 5
<class ‘list’>
- 方法split()默认值是以空格为分界,可传入其他分界值。若是以字符串中没有的字符为分界值,则返回一个只有一个字符串元素的列表
1 |
|
[‘1 2’, ‘3 4’, ‘5 6’]
[‘1 2 3 4 5’]
<class ‘list’>
1 2 3 4 5
4.4 字符串的合并
方法join()可以将字符进行合并。语法 'sep'.jion(seq)
。
- 其中sep为分隔符,可以为空。
- seq是要连接的元素序列、字符串、元组、字典
- 返回值:返回一个以分隔符sep连接各个元素后生成的字符串
1 |
|
1,2,3,4,5
1?2?3?4?5
11 2 3 4 521 2 3 4 531 2 3 4 541 2 3 4 55
4.5 字符串的替换
- 方法
replace(a,b)
可以指定替换字符串,后面的内容替换前面的
1 |
|
‘hello world’
4.6 字符串去掉空格
- 方法strip([chars])去掉两边字符串头尾指定的字符(默认为空格或换行符)或字符序列
- 方法lstrip([chars])去掉左边…
- 方法rstrip([chars])去掉右边…
1 |
|
‘hello python?’
1 |
|
‘hello python ‘
1 |
|
‘ hello python’
4.7 字符串填充
- zfill (width) 返回长度为 width 的字符串,原字符串右对齐,前面填充0
- rjust(width,[, fillchar])返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串
- ljust(width,[, fillchar])返回一个原字符串左对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串
1 |
|
0000000000000000000000000000hello python …wow!!!
hello python …wow!!!
hello python …wow!!!****************************
六、列表
1. 列表的创建
- 通过[]创建一个列表,列表里可以放任意类型的变量,以
,
隔开,不限制长度 - 使用list()函数创建列表,参数是列表的形式,且只有一个列表,一般会赋给一个变量
1 |
|
[1, 2.5, ‘hello’, True]
[[1, 2], [3, 4]]
1 |
|
TypeError: list expected at most 1 argument, got 2
2. 列表的操作符
1 |
|
4
[1, 2.5, ‘hello’, True, 123, 456]
[123, 456, 123, 456]
True
1
2.5
hello
True
1 |
|
[1, 2, 3, 4, 5, 6]
3. 列表的索引
长度为n的列表可以通过使用操作符[ ]
从0到n-1的正数来正向索引,也可以用-1到-n的负数来反向索引。
这种用一个具体位置数字访问列表元素的方法叫做索引,也叫列表的访问,一般只针对一个元素,同时索引出来的只是元素,不是一个单元素列表(除非元素本身就是列表)。
1 |
|
1
hello
True
2.5
索引可以用来赋值改变列表内容
1 |
|
[3, 2.5, ‘hello’, True]
4. 列表的切片
切片是通过使用操作符[ ]
索引多个元素,切片出来的是一个列表。列表、元组、字符串都可以通过切片来索引内容
切片格式为:item[x:y:z]
表示取出对象[x,y)
的范围,注意是左闭右开。每隔z个索引一个内容。
x省略表示从头索引,y省略表示索引到尾,z省略表示无需间隔。x,y都省略表示整个对象,可以用来将列表复制给另一个对象,即[:]
1 |
|
[1, 2]
[1, 2, 3, 4]
[1, 3, 5, 7]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
切片同样可以通过赋值来修改列表
1 |
|
[1, 2.5, 9, 8, 7, 6, 5, 4, 3, 2, 1]
也支持用负数进行切片,最后一个元素索引是-1。切记倒数切片的时候,依然是从前往后切。只是位置用负数表示而已
1 |
|
[6, 7, 8]
5. 列表的嵌套
列表中也可以放列表,访问多层列表,用多层的[]
来访问
1 |
|
[3, 4]
4
6. 列表的常用函数
常用的全局函数较少,主要是方法
- len()
- max()
- min()
- sorted() # 放在下面讲
1 |
|
6
6
1
7. 列表的常用方法
7.1 列表添加元素的方法
- 方法
append(obj)
用于添加列表元素,默认在列表最后添加obj,括号里的东西就是添加的内容,以括号里的格式为准,括号里是列表就往列表里添加列表
1 |
|
[123, 456, [123, 456]]
[123, 456, [123, 456], 123]
- 方法
insert(x,obj)
用于在指定位置x添加元素obj
1 |
|
[123, 789, 456, [123, 456], 123]
- 方法
extend(obj)
用于在列表末尾添加指定列表中的内容,注意这里的obj一定得是列表,并且添加的是内容,不是像append一样括号里是啥就加啥
1 |
|
[123, 456, [7, 8, 9]]
[123, 456, 7, 8, 9]
1 |
|
TypeError: ‘int’ object is not iterable
7.2 列表删除元素的方法
del 列表名[索引]
格式可以删除列表元素。可以用单个索引删除单个元素,也可以用切片删除多个元素
1 |
|
[3, 4, 5, 6, 7, 8, 9]
- 方法
remove()
可以删除指定内容的元素,括号里为内容,若有多个相同内容,则先删除第一个
1 |
|
[1, 3, 4, 8]
- 方法
pop(index=-1)
可以弹出索引元素,所谓弹出是指将弹出的元素赋给某个变量。括号里的参数为索引位置,默认弹出最后一个。
1 |
|
[1, 2, 3, 4, 5, 6, 7, 8]
9
[2, 3, 4, 5, 6, 7, 8]
7.3 列表的排序方法
方法sort()用于数字列表排序,排序之后,原列表被改变。如果排序时不要求原列表保持不变,这种效率更高一点,因为不用拷贝对象
1 |
|
[1, 1, 2, 3, 5, 7, 9, 10]
方法sort()还可以指定二级排序key,key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序
方法sort()还有参数reverse,其默认值为False,若指定为True,则翻转排序。(也有单独的方法list.reverse()用于列表翻转,倒序排列)
1 |
|
[-3, -1, 1, 2, 5, 7, 9, 10]
1 |
|
[1, 7, 2, 10, 9, 3, 5, 1]
列表排序还可以使用python的内置全局函数sorted()
二者的区别是,使用函数sorted()进行排序,原列表不会被改变,它是在原列表的拷贝对象上进行排序。函数sort()也有参数reverse和key,内置函数中细讲。
务必注意sorted()是全局函数,不是list的方法
1 |
|
[1, 5, 3, 9, 10, 2, 7, 1]
[10, 9, 7, 5, 3, 2, 1, 1]
1 |
|
[1, 5, 3, 9, 10, 2, 7, 1]
[10, 9, 7, 5, 3, 2, 1, 1]
7.4 列表的复制方法
- 方法list.copy()用于复制列表,返回复制后的新列表
- 也可以使用上文提到的切片赋值方法来复制
如果想开辟新的内存空间给复制后的变量不能简单的使用赋值语句,赋值语句是将两个变量指向同一个对象
1 |
|
2187198271168
2187198271168
2187198271360
2187198270912
7.5 列表的其他方法
- 方法list.count()用于计数,参数为待计数的内容,返回计数次数
- 方法list.index()用于定位索引,括号里是内容,返回结果是内容第一次出现在列表中的位置标号。列表中没有的内容会报错
- 方法list.reverse()用于列表翻转,倒序排列
- 方法list.clear()用于清空列表
1 |
|
2
6
None
[]
七、元组
1. 元组的定义
元组(tuple),用小括号()
定义,元素用逗号隔开。tuple一旦初始化就不能修改,属于不可变数据
如果可能,能用tuple代替list就尽量用tuple。
另外可以把字符串看作一种特殊的元组
1 |
|
tuple
定义tuple时,tuple的元素必须被确定下来,哪怕他是空的。
注意如果要定义一个只有1个元素的tuple,必须加一个逗号,因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,所以结果是一个数字
1 |
|
<class ‘tuple’>
<class ‘int’>
<class ‘tuple’>
2. 元组不可变的理解
tuple所谓的“不可变”是说,tuple的每个元素,中间的指向关系永远不变。即指向’a’,就不能改成指向’b’,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
虽然tuple不可改变,但它可以包含可变的对象,比如list列表。所以要创建一个内容也不变的tuple,就必须保证tuple的每一个元素本身也不能变。
下面这段代码,表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list。
1 |
|
(‘a’, ‘b’, [‘X’, ‘Y’])
3. 元组的索引与切片
和列表相同,也可以通过下标来访问,截取,组合。虽然可以用切片索引元素,但不能修改元素
1 |
|
3
(1, 2)
8
(3, 4, 5, 6, 7, 8, 9)
4. 元组的运算符
补充:
- 可以通过del语句来删除整个元组
1 |
|
NameError: name ‘a’ is not defined
5. 元组的常用函数
- tuple.count()计量某个数值在元组中出现的次数
- max()返回元素最大值
- min()返回元素最小值
1 |
|
2
3
1
6. 拆包
拆包就是python把元组(或者其他序列数据类型)的元素拆分开来,逐个赋给新的变量
使用这个功能可以给多个变量赋值或交换变量名,比其他语言要简洁
1 |
|
4 5 6
4 5 6 7
5 4
拆包也可以遍历元组或列表组成的序列
1 |
|
1 2 3
4 5 6
7 8 9
八、字典
1. 字典的创建
python通过{}
创建字典结构,或者使用dict()函数。字典是一种键值对结构,keys:values
,键值对中间用,
隔开,键值对在字典里是无序的。
键只可以为数字、字符串、元组,为不可变对象,且键唯一,而值可以为任何变量类型,且不唯一。
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;而list查找和插入的时间随着元素的增加而增加;
- 需要占用大量的内存,内存浪费多;而list占用空间小,浪费内存很少。
1 |
|
字典里只允许存在一个key,创建时如果同一个key被赋值两次,后一个值会覆盖前面的
1 |
|
dict[‘Name’]: 小菜鸟
字典的key必须是不可变对象的原因
因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。
这个通过key计算位置的算法称为哈希算法(Hash)。要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、数字、元组都是不可变的,因此,可以放心地作为key
2. 字典的索引和操作符
字典不能像列表和元组一样通过位置来索引,只能通过keys来索引。字典是可变的,所以可以通过索引添加、修改、删除字典
1 |
|
{‘a’: 2, ‘b’: 2, ‘c’: 3, ‘d’: 4}
删除需要用到del
操作符
- del dict[ ]用于删除键值对
- del dict_name用于删除整个字典
1 |
|
{‘b’: 2, ‘c’: 3}
NameError: name ‘dict1’ is not defined
操作符in
可以判断键是否在字典中,不能直接判断值是否在其中
1 |
|
True
3. 字典常用函数
4. 字典常用方法
4.1 获取字典内容的方法
dict.keys()
,dict.values()
,dict.items()
分别以迭代器形式返回字典中的所有键、值、键值对。可以用list()函数将迭代器转化为列表,见后面迭代器内容。通常会搭配fo循环使用
方法使用时记得加括号!!!容易漏
1 |
|
dict_keys([123, ‘secend’, (1, 2, 3)])
dict_values([1, ‘hello’, {‘123’: 1, ‘secend’: ‘hello’}])
dict_items([(123, 1), (‘secend’, ‘hello’), ((1, 2, 3), {‘123’: 1, ‘secend’: ‘hello’})])
[123, ‘secend’, (1, 2, 3)]
123 1
secend hello
(1, 2, 3) {‘123’: 1, ‘secend’: ‘hello’}
- 方法
dict.get(key, default=None)
可以返回指定键的值,如果键不在字典中返回默认值None。默认值并不影响原字典中的键值对- key – 字典中要查找的键
- default – 如果指定键的值不存在时,返回该默认值
1 |
|
1
None
python
{123: 1, ‘secend’: ‘hello’, (1, 2, 3): {‘123’: 1, ‘secend’: ‘hello’}}
- 方法
dict.setdefault(key, default=None)
也会返回对应的值。如果 key 不在字典中,则插入 key 及设置的默认值,并返回默认值 ,默认值为 None
1 |
|
python
{123: 1, ‘secend’: ‘hello’, (1, 2, 3): {‘123’: 1, ‘secend’: ‘hello’}, 789: ‘python’}
4.2 删除字典元素的方法
dict.pop(key[,default])
用于删除字典中的键值对,key值必须给出,返回被删除的value。如果没有 key,返回 default 值
1 |
|
123
{‘secend’: 456, ‘third’: 789}
popitem()
方法删除字典中的最后一对键和值,并以元组形式返回。如果字典已经为空,就报出KeyError异常
1 |
|
<class ‘tuple’>
(‘third’, 789)
{‘first’: 123, ‘secend’: 456}
dict.clear()
删除字典内所有元素
1 |
|
{}
4.3 更新字典的方法
dict.update(dict1)
将dict1更新到指定字典dict里。所谓更新,即没有就添加,有相同的就修改,以dict1中的为准
1 |
|
{‘hello’: 123, ‘python’: 100, ‘world’: 789}
4.4 复制字典的方法
dict.copy()
函数返回一个字典的浅复制,浅复制就是拷贝一个新的对象给另一个变量,改变新对象并不会影响原对象
1 |
|
{‘first’: 123, ‘secend’: 456, ‘third’: 789}
{‘first’: 123, ‘secend’: 456, ‘third’: 789}
{‘first’: ‘abc’, ‘secend’: 456, ‘third’: 789}
4.5 创建新字典的方法
dict.fromkeys(seq[, value])
函数用于创建一个新字典,以序列 seq 中元素做字典的键,value为字典所有键的初始值,value只能输入一个值
1 |
|
{‘first’: ‘python’, ‘secend’: ‘python’, ‘third’: ‘python’}
九、集合
集合(set)和dict类似,也是一组key的集合 (不可变对象!),但不存储value。由于key不能重复,所以,在set中,没有重复的key
1. 集合的创建
可以使用大括号 { }
或者 set()
函数创建集合。创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典
1 |
|
{1, 2, 3, 4, 5, 6, 8}
{(1, 2), (3, 4)}
{‘n’, ‘p’, ‘y’, ‘o’, ‘h’, ‘t’}
set()函数创建字符串集合的注意点:
- 用set()创建字符串集合时,如果小括号内只有一个字符串,会拆分为单个字母
- 用set()创建多个字符串,需要将多个字符串用[]{}()括起来
1 |
|
{‘python’}
{‘hello’, ‘python’}
{‘n’, ‘p’, ‘y’, ‘o’, ‘h’, ‘t’}
{‘hello’, ‘python’}
python中还有一种集合是不可变集合:不能再添加或删除任何元素的集合 (用到再详细展开)
通过内置函数frozenset()
创建,参数为iterable,返回frozenset对象,如果不提供任何参数,默认会生成空集合
需要使用不可变集合的原因:
在集合的关系中,有集合的中的元素是另一个集合的情况,但是普通集合(set)本身是可变的,那么它的实例就不能放在另一个集合中(set中的元素必须是不可变类型)。所以,frozenset提供了不可变的集合的功能,当集合不可变时,它就满足了作为集合中的元素的要求,就可以放在另一个集合中了。
1 |
|
<class ‘frozenset’>
<class ‘set’>
2. 集合的操作符
2.1 运算操作符
- 交集a&b
- 并集a|b ,
- 差集:集合a中包含而集合b中不包含的元素a-b ,b-a相反
- 两个集合中不重复的元素集合: a^b
- 集合的相等判定:当且仅当两个集合的内容一摸一样时,两个集合才相等
1 |
|
{‘a’, ‘d’, ‘c’, ‘b’, ‘g’, ‘j’, ‘h’, ‘e’, ‘f’, ‘k’}
{‘a’, ‘c’, ‘g’, ‘e’}
{‘d’, ‘f’, ‘b’}
{‘d’, ‘j’, ‘b’, ‘h’, ‘f’, ‘k’}
True
集合的部分方法能够实现上述相同功能:
- union() 方法返回两个集合的并集,重复的元素只会出现一次。set.union(set1, set2…)
- intersection() 方法用于返回两个或更多集合的交集。set.intersection(set1, set2 …)
- difference() 方法用于返回集合的差集。set.difference(set)
- symmetric_difference() 方法返回两个集合中不重复的元素集合
2.2 其他操作符
in用于判断元素是否在集合中
1 |
|
True
3. 集合的常用函数
- len(s)计算集合元素个数
1 |
|
7
4. 集合的常用方法
4.1.添加元素
- s.add( x ),将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作
- s.update( x ),可以将新的元素或集合更新到当前集合中。参数可以是列表、元组等
1 |
|
{1, ‘12’, 2, 3, 4, 5, 6, 8, 9}
1 |
|
{‘Google’, ‘Taobao’, ‘Runoob’}
{‘Google’, ‘Taobao’, ‘Facebook’, ‘Runoob’}
{‘Taobao’, ‘Runoob’, ‘o’, ‘Y’, ‘Facebook’, ‘a’, ‘h’, ‘Google’}
4.2.删除元素
- s.remove( x ),将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误
- s.discard( x ),也是移除集合中的元素,且如果元素不存在,不会发生错误
- s.pop(),随机返回集合中的一个元素。pop()没有参数,随机删除一个
- s.clear()清空集合
1 |
|
{1, 4, 5, 6}
1 |
|
{2, 3, 4, 5, 6}
{‘p’, ‘y’, ‘o’, ‘h’, ‘t’}
1 n
1 |
|
set()