嘀嘀嘀~~~  页面这在飞快的跑来 . . .

Python数据结构


序列概览

  • Python中有6种内建的序列。其中列表和元组是最常见的类型。其他包括字符串、Unicode字符串、buffer对象和xrange对象。
  • 列表和元组的主要区别是列表可以修改,而元组不能,如果要根据要求来添加元素,这时候列表适用性会更好,但是当序列不能修改的时候,使用元组则更合适,使用元组与Python的运作方式相关。
  • 在python中几乎所有的情况下列表都可以替代元组,但是特殊情况不能(当使用元组作为字典的不可修改的键时,此时键不能修改,所以不能使用列表) 例如:
#定义一个学生序列
>>> stuinfo=['zhangsan','lisi','wangwu',18,20]

同时序列中还可以包含序列,例如数据库:database

#定义学生姓名和学生年龄,然后再定义一个属于自己的数据库将两个列表加入
>>> stuname=['zhangsan','lisi','wangwu']
>>> stuage=[18,20,16]
>>> database=[stuname,stuage]
>>> database
[['zhangsan', 'lisi', 'wangwu'], [18, 20, 16]]

注意: python还有一种名为容器(container)的数据结构,容器可以包含其他任意对象,容器主要包括序列和映射(例如:字典)两类。序列的每个元素都有自己的编号,而映射每个元素则有一个叫做“键”的名字。集合是另一种容器。

通用序列操作

python中所有序列类型都可以进行一些特定的操作,这些操作包括:索引、分片、相加、相乘以及检查某个元素是否属于序列的成员–>成员资格检测 除此之外,Python还有计算序列长度,找出最大和最小元素的内建函数。

索引

序列中所有元素都有编号,这些编号是从0开始,依次递增,访问这些元素通过下标即可访问,而这个编号就是索引,例如:

>>> database[0]
['zhangsan', 'lisi', 'wangwu']
>>> database[1]
[18, 20, 16]


#字符串序列的索引
>>> str='hello'
>>> str[0]
'h'
>>> str[1]
'e'

注意: 字符串就是一个由字符组成的序列,索引0指向第一个元素 以上这就是索引,所有序列中都可以通过元素编号的方式进行索引,当使用负数索引时,Python会从右边到左进行所有,-1是从序列的最后一个元素开始,如下:

#从最后一个元素开始
>>> str[-1]
'o'
#从倒数第二个元素开始
>>> str[-2]
'l'

分片

同样的和索引类似,分片是通过冒号操作来访问一定范围内的元素,例如:

# 构建一个序列tag,里面包含一个元素
>>> tag=['https://www.cnblogs.com/yangyuqig/p/10101663.html']

# 拿到这个元素后通过分片取出一个范围的值
>>> tag[0][0:24]
'https://www.cnblogs.com/'

由上所知,分片操作的的实现需要提供两个索引作为边界,是一个左闭右开的区间,也就是第1个索引包含在分片内,而第2个索引不包含在这个分片内,例如:

>>> num=[1,2,3,4,5,6,7,8,9,10]
# 表示从第四个到最后一个元素
>>> num[3:10]
[4, 5, 6, 7, 8, 9, 10]

除了上述方案,也可以通过显示方式进行操作:

分片快捷操作
>>> num[0:3]
# 取到前面3个数据
[1, 2, 3]
分片步长操作

分片操作可以给元素设置步长,在开始和结束的时候指定相应步长获取元素,例如:

# 按照步长为2返回第1个和第6个之间的元素
>>> num[0:6:2]
[1, 3, 5]

另外需要注意的是负数步长是从元素尾部到前遍历整个序列,所以负数的分片开始索引一定要大于结束索引

>>> num[7:-1]
[8, 9]

当开始索引和结束索引是负数时开始所以必须小于结束索引:

>>> num[-9:-1]
[2, 3, 4, 5, 6, 7, 8, 9]

对于一个正数步长,Python会从序列的头部开始向右提取元素,直达最后一个元素,而对于负数步长,则是从序列的尾部开始向左提取元素,直达提取到第一个,例如:

# 提取前6个元素,步长为2
>>> num[:6:2]
[1, 3, 5]
# 提取从后往前的8个元素,步长为2
>>> num[:2:-2]
[10, 8, 6, 4]

序列相加

序列相加通过加号“+”进行序列和序列之间的连接操作:

>>> 'hello'+' world !'
  'hello world !'

>>> [1,2,3]+['zhangsan','lisi','wangwu']
[1, 2, 3, 'zhangsan', 'lisi', 'wangwu']

注意:只有相同类型的序列才能进行连接操作。

序列相乘

一个数字x乘以一个序列会产生一个新的序列,原来的序列会被重置成x次

>>> ['hello'+' world !']*3
['hello world !', 'hello world !', 'hello world !']

成员资格

检查一个元素是否在一个序列中使用运算符in进行检查, in运算符返回检查某个条件的布尔值,若为真返回true,否则返回false,例如:

>>> str='hello'
>>> 'h' in str
True

>>> 'x' in str
False

序列长度、最大值和最小值

序列长度、最大值和最小值使用内建函数len、max、min进行检测,len返回序列中所包含的元素数量,max和min分别返回序列中最大值和最小值的元素

>>> len([11,34,23])
3
>>> max(11,34,23)
34
>>> min(11,34,23)
11
  • 列表俗称是 Python 中的苦力,列表可变(可以改变列表的内容)
  • 列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
  • 列表的数据项不需要具有相同的类型 创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。

列表

列表函数

list 函数

如果对字符串赋值后想要改变字符串中的某个值,因为字符串不能像列表一样可更改,如果想改变这时候可以利用 list 函数,如下:

>>> ll=list('hello')
>>> ll
['h', 'e', 'l', 'l', 'o']
>>> ll[2]
'l'
>>> ll[2]='5'
>>> ll
['h', 'e', '5', 'l', 'o']

注意:list 函数适用于所有类型的序列,而不只是字符串

len 函数

len 函数返回列表中的元素个数

>>> list1 = ['baidu', 'google', 12, 23];
>>> len(list1)
4

max 函数

max 函数返回列表元素最大值

>>> list_num=[2,3,5,6,8,12]
>>> max(list_num)
12

min 函数

返回列表元素最小值

>>> list_num=[2,3,5,6,8,12]
>>> min(list_num)
2

列表方法

列表提供了几个详细的方法,这些方法用于检查或者修改列表中的内容

append

append 方法用于在列表的末尾追加新的内容

list_append = [1,2,3,4]
list_append.append(5)
list_append
[1, 2, 3, 4, 5]

count

count 方法用于统计某个元素在列表中出现的次数

num
[1, 2, 3, 4, 5, 5, 5, 5, 6]
# 统计num列表中5出现的次数
num.count(5)
4

# 统计字母a出现的次数
name=['a','a','abf','ark','nhk']

name.count('a')
2

extend

extend 方法表示追加内容,它可以在列表的末尾一次性追加另一个序列中的多个值,也就是用新列表扩展原有列表

a =[1,2,3]
b = [4,5,6]
# 将列表b追加在列表a后面
a.extend(b)
a
[1, 2, 3, 4, 5, 6]

此操作和列表的相加操作,但是追加操作改变原有列表,而相加不改变原有列表,例如:

a = [1,2,3]
b = [4,5,6]
a + b
[1, 2, 3, 4, 5, 6]
# 连接操作不改变原有列表
a
[1, 2, 3]

index

index 方法用于从列表中找出某个元素第一次匹配的位置的索引位置

content = ['where','who','lisi','cntent','who']
content.index('who')
1

注意: 以上方法中有两个位置有‘who’,但是只找出了第一次匹配的索引位置元素

insert

insert 方法用于像列表中插入对象

num = [1,2,5,6,7]
num.insert(2,3)
num
[1, 2, 3, 5, 6, 7]
num.insert(3,4)
num
[1, 2, 3, 4, 5, 6, 7]

pop

pop 方法会移除列表中的一个元素(默认是最后一个),并且返回该元素的值

x = [1,2,3]
x.pop()
3
x
[1, 2]
x.pop()
2
x
[1]

注意:pop 方法是唯一一个既能修改列表又能返回元素值的方法(除了None),pop 和 append 方法是 Python 中数据结构的出栈和入栈,如果追加(append)刚刚出栈(pop)的值,得到的还是原来的列表

x = [1,2,3]
x.append(x.pop())
x
[1, 2, 3]

remove

remove 方法用于移除列表中第一个匹配的元素

content
['where', 'who', 'lisi', 'cntent', 'who', 'who']
# 移除了第一个匹配的元素
content.remove('who')
content
['where', 'lisi', 'cntent', 'who', 'who']

reverse

reverse 方法是将列表中的元素进行反转操作

x
[1, 2, 3]
# 元素反向存储
x.reverse()
x
[3, 2, 1]

sort

sort 方法用于在原位置排序,‘原位置排序’意味着改变原来的列表而让列表中的元素有顺序排列

x = [2,3,5,6,1,4,7]
x.sort()
x
[1, 2, 3, 4, 5, 6, 7]

clear

clear 方法用于清空列表

>>> list1=['baidu', 'google', 12, 23]
>>> list1
['baidu', 'google', 12, 23]
# 清空列表内容
>>> list1.clear()
>>> list1
[]

copy

copy 方法是复制列表

>>> list1 = ['baidu', 'google', 12, 23];
>>> list1.copy()
['baidu', 'google', 12, 23]
>>> list2 = list1.copy()
>>> list2
['baidu', 'google', 12, 23]

列表基本操作

列表可以使用所有适用于序列的标准操作,比如第7天所学的索引、分片、连接和相乘,更有趣的是,列表是可以修改的,也就是定义的列表内容可以根据需求更改,本节介绍一些改变列表的方法:如元素赋值、元素删除、分片赋值以及列表方法(但是请注意,并不是所有的列表方法都能真正改变列表)

改变列表:元素赋值

在列表中要给指定的元素赋值时,我们需要指定特定的索引标记来为列表中某个特定的,位置明确的元素赋值,比如 x[3]=5

x=[1,2,3,4,5]
x
[1, 2, 3, 4, 5]
# 改变列表第四个元素的内容
x[3]=5
x
[1, 2, 3, 5, 5]

注意: 不能为一个位置不存在的元素赋值,如果列表长度为2,则不能为索引为10 的元素进行赋值,如果需要赋值则需要创建一个长度为11的列表。

删除列表元素

若要删除列表中的元素,直接利用del删除即可

# 定义长度为4的姓名列表
names=['zhangsan','lisi','wangwu','zhaoliu']
names
['zhangsan', 'lisi', 'wangwu', 'zhaoliu']

# 删除第三个元素
del names[2]

# 最后列表长度由4变为3
names
['zhangsan', 'lisi', 'zhaoliu']

del 语句还能用于删除其他元素,也可以用于变量的删除操作。

分片赋值

在 Python 中对序列或者列表的分片操作是一个很强大的特性,分片赋值会显得更加强大,例如:

# 定义一个list
name = list('Pyther')

# 改变 list 中的最后两个值
name[4:]='on'
name
['P', 'y', 't', 'h', 'o', 'n']

从上可知,程序可以一次为多个元素赋值,在分片赋值时,可以使用与原序列不等长的序列将分片替换,例如:

name_re = list('perl')
name_re
['p', 'e', 'r', 'l']
# 分片替换
name_re[1:] = list('ython')
name_re
['p', 'y', 't', 'h', 'o', 'n']

分片赋值还可以在不需要更改原有列表任何内容的情况下进行新元素插入

num = [1,4,5]
# 在第一个元素后插入新的元素
num[1:1]=[2,3]
num
[1, 2, 3, 4, 5]

同理也可以通过分片操作来删除列表中的元素,同样也支持负数分片操作

num
[1, 2, 3, 4, 5]
# 给第一个和迪桑元素之间分片赋值一个空序列,即删除元素
num[1:3] = []
num
[1, 4, 5]

# 负数分片操作
num[-1:-1] = [5,5,5]
num
[1, 2, 3, 4, 5, 5, 5, 5, 6]
  • Python 的元组与列表类似,不同之处在于元组的元素不能修改。
  • 元组使用小括号(),列表使用方括号[]。

元组

元祖基本操作

创建元组

元组创建很简单,只需要在括号中添加元素(不需要括号也可以),并使用逗号隔开即可。

>>> tup1 = ('baidu', 'google', 12, 34); 
>>> tup2 = (1, 2, 3, 4, 5 );
>>> tup3 = "a", "b", "c", "d";

# 创建空元组
>>> tup4 = ()

# 查看tup4和tup3的类型
>>> type(tup4)
<class 'tuple'>
>>> type(tup3)
<class 'tuple'>

注意: 元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用,如下:

>>> TupNum = (34)   
>>> type(TupNum)   # 不加逗号是整型
<class 'int'>
>>> TupNum = (34,)
>>> type(TupNum)  # 加上逗号变元组
<class 'tuple'>

元组与字符串类似,下标索引从 0 开始,可以对元组进行截取,组合等操作。

访问元组

元组的访问和序列访问元素一样,都是通过下标索引进行访问操作

>>> tup1 = ('baidu', 'google',1,2)
>>> tup2 = (1, 2, 3, 4, 5, 6, 7)
>>> tup1[0:2]
('baidu', 'google')
>>> tup2[1:4]
(2, 3, 4)

修改元组

元组中的值一旦定义就不能修改,但是我们可以通过元组与元组之间的连接关系来对元组进行修改,例如:

>>> tup1 = ('baidu', 'google',1,2)
>>> tup2 = (1, 2, 3, 4, 5, 6, 7)
>>> tup1 + tup2
('baidu', 'google', 1, 2, 1, 2, 3, 4, 5, 6, 7)

注意: 以下修改元组属于非法操作,因为元组不支持通过索引列来修改,只能对元组进行复制和连接操作

tup1[0] = 100 (不能进行此操作)

删除元组

由于元组的不可修改性,所以元组中的元素值是不允许删除的,但我们可以使用 del 语句来删除整个元组,如下实例:

tup1 = ('baidu', 'google',1,2)
 
print (tup)
del tup;
print ("删除后的元组 tup : ")
print (tup)

# 报错信息如下,证明整个元组已经被删除
删除后的元组 tup1 : 
Traceback (most recent call last):
  File "tupple.py", line 29, in <module>
    print(tup1)
NameError: name 'tup1' is not defined

元组运算符

与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。总而言之对整个元组进行一些运算后就会生成一个新的元组。

元组求长度

元组求长度使用运算函数 len ,如下

# 求元组tup1的长度
>>> tup1 = ('baidu', 'google',1,2)
>>> len(tup1)
4

连接元组

两个甚至对个元组的连接使用 + 连接符,例如:

>>> tup1 = (1,2,3)
>>> tup2 = (4,5,6)
>>> tup3 = (7,8,9)
>>> tup1 + tup2 + tup3
(1, 2, 3, 4, 5, 6, 7, 8, 9)

复制元组

tup1 = ('abc')
# 元组复制需要加上分隔符后面复制的内容就按照分隔符分隔开
(tup1,) * 3
('abc', 'abc', 'abc')

判断元素

判断元组中元素是否存在使用关键字 in 进行判断,判断结果返回布尔值

>>> tup1
'abc'
>>> 'a' in tup1
True

元组中指定位置元素访问

和序列一样,元组中的元素同样可以使用索引号访问指定位置的元素,例如:

>>> content = ('hello','world','!')
>>> content
('hello', 'world', '!')
>>> content[1:]
('world', '!')
>>> content[:2]
('hello', 'world')
>>> content[-1]
'!'
>>> content[-2]
'world'

元组内置函数

和列表一样,元组同样也拥有一些内置函数,这些函数用于判元组中的元素大小以及将元组做相应的转换

#计算元组元素个数。
len(tuple)
#返回元组中元素最大值。
max(tuple)
#返回元组中元素最小值。
min(tuple)	
#将列表转换为元组。	
tuple(seq)

类与对象

面向对象

面向对象是一种抽象,是一种用分类的方式看待问题的方法,用 Java 的编程思想来说就是:万物皆对象;面向对象有三大特性:封装、继承、多态。

面向对象是一种用分类的方式看待问题的方法,一个分类就是一个类,可以把类看作是一个抽象的模板,如:Car 类。

对象

对象是根据类创建出来的一个个实例。

基本使用

类的定义

# 类的定义class Car:    pass

对象的创建

# 创建 Car 的实例对象 cclass Car:    pass	c = Car()

类中定义属性

# 定义 Car 类的属性 nameclass Car:    name = 'BMW'

类中的方法

内置方法

Python 创建任何一个类的时候,都会包含一些内置的方法,主要包括如下:

方法 说明
__init__ 构造函数,在生成对象时调用
__del__ 析构函数,释放对象时使用
__repr__ 打印,转换
__setitem__ 按照索引赋值
__getitem__ 按照索引获取值
__len__ 获得长度
__cmp__ 比较运算
__call__ 函数调用
__add__ 加运算
__sub__ 减运算
__mul__ 乘运算
__div__ 除运算
__mod__ 求余运算
__pow__ 乘方

自定义方法

Python 有三种常见的方法,分别为:实例方法、类方法、静态方法,这三种方法都定义在类中。

类方法

类方法是将类本身作为对象进行操作的方法。

定义与使用

'''
类方法(可调类变量、可被实例调用、可被类调用)
1、类方法通过@classmethod装饰器实现,只能访问类变量,不能访问实例变量;
2、通过cls参数传递当前类对象,不需要实例化。
'''
class Car(object):
    name = 'BMW'
    def __init__(self, name):
        self.name = name
    @classmethod
    def run(cls,speed):
        print(cls.name,speed,'行驶')
# 访问方式1
c = Car("宝马")
c.run("100迈")
# 访问方式2
Car.run("100迈")
静态方法

静态方法是类中的函数,不需要实例。

定义与使用

'''
静态方法(可调类变量、可被实例调用、可被类调用)
1、用 @staticmethod 装饰的不带 self 参数的方法;
2、静态方法名义上归类管理,实际中在静态方法中无法访问类和实例中的任何属性;
3、调用时并不需要传递类或实例。
'''
class Car(object):
    name = 'BMW'
    def __init__(self, name):
        self.name = name
    @staticmethod
    def run(speed):
        print(Car.name,speed,'行驶')
        
# 访问方式1
c = Car("宝马")
c.run("100迈")
# 访问方式2
Car.run("100迈")
实例方法

实例方法就是类的实例能够使用的方法。

定义与使用

# 实例方法(可调类变量、可调实例变量、可被实例调用)
# 第一个参数强制为实例对象 self。
class Car(object):
    name = 'BMW'
    def __init__(self, name):
        self.name = name
    def run(self,speed):
        print(self.name,speed,'行驶')

# 访问
c = Car("宝马")
c.run("100迈")

类的继承

定义与使用

# 基本语法:class ClassName(BaseClassName)
# 父类
class Car(object):
    name = 'BMW'
    def __init__(self, name):
        self.name = name
    def run(self,speed):
        print(self.name,speed,'行驶')
        
# 子类
class BMWCar(Car):
    conf = "经济适用型"
    pass

# 调用父类 Car 中 run 方法
bc = BMWCar("BMW经济适用型轿车")
bc.run("100迈")

类的多态

定义与使用

# 父类
class Car(object):
    name = 'BMW'
    def __init__(self, name):
        self.name = name
    def run(self,speed):
        print('Car-->',self.name,speed,'行驶')

# 子类1
class BMWCar(Car):
    def run(self,speed):
        print('BMWCar-->',self.name,speed,'行驶')

# 子类2
class SVWCar(Car):
    def run(self,speed):
        print('SVWCar-->',self.name,speed,'行驶')

# 调用 run 方法
c = Car("Car")
c.run("120迈")

bc = BMWCar("宝马")
bc.run("100迈")

sc = SVWCar("大众")
sc.run("80迈")

# 输出结果
'''
Car--> Car 120迈 行驶
BMWCar--> 宝马 100迈 行驶
SVWCar--> 大众 80迈 行驶
'''

字典

Python 中的字典提供了一种灵活的访问和组织数据的方式

  • 字典是由很多值组成的集合
  • 字典的索引可以是不同的数据类型,同样也不止是整数,也有字符串
  • 字典的索引被称为“键”,键及键所关联的值叫键值对(类似于Java中的Map集合)
  • 字典是另一种可变容器模型,且可存储任意类型对象。
  • 字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
dictionary  = &#123;'url1':'baidu', 'url':'google', 'num1':12, 'num2':34&#125;;

键一般是唯一的,如果键重复,最后的一个键值对会替换前面的键值对,值没有唯一性要求,如下:

dic1 = &#123;'name':'zhangsan','age':23,'address':'BeiJing','name':'lisi'&#125;
# 查看字典值发现重复的键值后面的替换前面的
dic1
&#123;'name': 'lisi', 'age': 23, 'address': 'BeiJing'&#125;

dic1['name']
'lisi'

值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组,如下:

dict = &#123;'Alice': '2341', 'Beth': '9102', 'Cecil': '3258',('a','b'):(12,43)&#125;

访问字典数据

创建一个字典,并访问数据字典内容,以下字典的键是‘size’,’color’,’character’,这些键对应的值是‘big’,’white’,’gentle’,访问字典的值通过方括号里面添加键就可以直接进行访问,例如:

MyDog = &#123;'size':'big','color':'white','character':'gentle'&#125;

# 字典值通过[‘键’]来访问
print(MyDog['size'])
 big   #输出结果

print('My Dog has '+MyDog['color']+' fur.' + ' and it has a ' + MyDog['character']+' character')
My Dog has white fur. and it has a gentle character #输出结果

同样的,字典也可以用整数作为键,和列表的索引类似,只是字典的值是任何整数类型都行,不必要从0开始,因为键值的数据类型是任意的,如下:

MyCon = &#123;12:'big',0:'white',354:'gentle',1:'good'&#125;
# 访问键为 12 的字典值
MyCon[12]
'big'
# 访问键为 0 的字典值
MyCon[0]
'white'

因为字典是不排序的,所以不能像列表那样切片。如果访问字典中不存在的键,将导致 KeyError 出错信息。这很像列表的“越界” IndexError 出错信息。在交互式环境中输入以下代码,并注意显示的出错信息,因 为没有’color’键:

dic1 = &#123;'name':'zhangsan','age':23,'address':'BeiJing'&#125;
#找字典中键为 'color' 的值
dic1['color']
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'color'

修改字典元素

添加和更新字典数据

向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对如下实例:

dict = &#123;'Name': 'Fiona', 'Age': 10, 'Class': 'Three'&#125;
# 更新
dict['Age'] = 8 
# 添加
dict['School'] = "Middle School" 
# 查看字典数据 
dict
&#123;'Name': 'Fiona', 'Age': 8, 'Class': 'Three', 'School': 'Middle School'&#125;

删除字典元素

对字典元素的删除操作能单一删除也能将整个字典清空,显示的删除一个字典使用 del 命令“

dict = &#123;'Name': 'Fiona', 'Age': 10, 'Class': 'Three'&#125;

# 删除键是'Name'的条目 
del dict['Name']  

# 清空字典所有条目
dict.clear()  

# 删除整个字典元素
del dict          
 
print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

以上打印语句这会引发一个异常,因为用 del 后的字典不再存在:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print("dict['Age']: ", dict['Age'])
TypeError: 'type' object is not subscriptable

字典键的特性

字典值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的,但键不行。

两个重要的点需要记住:

不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,如下实例:

dict = &#123;'Name': 'Fiona', 'Age': 10, 'Name': 'Manni'&#125; 
 
print "dict['Name']: ", dict['Name']

# 以上实例输出结果:

dict['Name']:  Manni

键必须不可变,所以可以用数字,字符串或元组充当,所以用列表就不行,如下实例:

dict = &#123;['Name']: 'Fiona', 'Age': 10&#125; 
 
print "dict['Name']: ", dict['Name']

# 以上实例输出结果:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    dict = &#123;['Name']: 'Zara', 'Age': 7&#125; 
TypeError: list objects are unhashable

字典的函数

len()

len() 方法计算字典元素个数(键的总个数)

>>> dict = &#123;'Name': 'Fiona', 'Age': 10, 'class': 'Three'&#125;  
>>> len(dict)     
3

str()

str() 方法输出字典中可以打印的字符串标识

>>> dict = &#123;'Name': 'Runoob', 'Age': 10, 'Class': 'Three'&#125;
>>> str(dict)
"&#123;'Name': 'Runoob', 'Age': 10, 'Class': 'Three'&#125;"

type()

type() 方法返回输入的变量类型,如果变量是字典就返回字典类型

>>> dict = {'Name': 'Runoob', 'Age': 10, 'Class': 'Three'}
>>> type(dict)
<class 'dict'>

字典的方法

dict.clear()

删除字典内所有元素,clear() 方法没有任何返回值,实例如下:

dict = &#123;'Name': 'Fiona', 'Age': 10&#125;

print ("字典长度 : %d" %  len(dict))
dict.clear()
print ("字典删除后长度 : %d" %  len(dict))

# 输出结果为:
字典长度 : 2
字典删除后长度 : 0

dict.copy()

copy() 方法对字典进行复制

dict = &#123;'Name': 'Runoob', 'Age': 7, 'Class': 'First'&#125;

dict11 = dict.copy()
print(dict11)
print("新复制的字典为 : ", dict11)

dict1 = &#123;'user': 'runoob', 'num': [1, 2, 3]&#125;

# 浅拷贝: 引用对象  赋值
dict2 = dict1  
# 拷贝
dict3 = dict1.copy()  

# 修改 data 数据
dict1['user'] = 'root'
dict1['num'].remove(1)

# 输出结果
print(dict1)
print(dict2)
print(dict3)

实例中 dict2 其实是 dict1 的引用,即别名,所以输出结果都是一致的,dict3 对父对象进行了深拷贝,深拷贝不会随dict1 修改而修改,子对象是浅拷贝所以随 dict1 的修改而修改,即赋值会随父对象的修改而修改,拷贝不会随父对象的修改而修改,以上结果输出如下:

&#123;'Name': 'Runoob', 'Age': 7, 'Class': 'First'&#125;
新复制的字典为 :  &#123;'Name': 'Runoob', 'Age': 7, 'Class': 'First'&#125;

&#123;'user': 'root', 'num': [2, 3]&#125;
&#123;'user': 'root', 'num': [2, 3]&#125;
&#123;'user': 'runoob', 'num': [2, 3]&#125;

dict.fromkeys()

创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值,该方法返回一个新的字典

fromkeys() 方法语法

dict.fromkeys(seq[, value])
# 参数
seq -- 字典键值列表。
value -- 可选参数, 设置键序列(seq)对应的值,默认为 None。

实例:

# dict.fromkeys(seq[, value])
seq = ('name', 'age', 'class')

# 不指定值
dict = dict.fromkeys(seq)
print("新的字典为 : %s" % str(dict))

# 赋值 10
dict = dict.fromkeys(seq, 10)
print("新的字典为 : %s" % str(dict))

# 赋值一个元组
dict = dict.fromkeys(seq,('zs',8,'Two'))
print("新的字典为 : %s" % str(dict))

执行结果返回一个新的字典,如果不指定值默认为None,以上结果输出结果为:

新的字典为 : &#123;'name': None, 'age': None, 'class': None&#125;
新的字典为 : &#123;'name': 10, 'age': 10, 'class': 10&#125;
新的字典为 : &#123;'name': ('zs', 8, 'Two'), 'age': ('zs', 8, 'Two'), 'class': ('zs', 8, 'Two')&#125;

dict.get()

返回指定键的值,如果值不在字典中返回default值

get() 方法语法

dict.get(key, default=None)
# 参数key -- 字典中要查找的键。default -- 如果指定键的值不存在时,返回该默认值值。

实例:

# get ()方法的应用举例dict = &#123;'Name': 'Mary', 'Age': 20&#125;
print ("Age 值为 : %s" %  dict.get('Age'))print ("Name 值为 : %s" %  dict.get('Name'))print ("Sex 值为 : %s" %  dict.get('Sex', "NA"))

以上结果输出为:

Age 值为 : 20Name 值为 : MarySex 值为 : NA

key in dict

如果键在字典dict里返回true,否则返回false

dict = &#123;'Name': 'Mary', 'Age': 20,'Address':'BeiJing'&#125;

# 检测键 Age 是否存在
if 'Age' in dict:
    print("键 Age 存在")
else:
    print("键 Age 不存在")

# 检测键 Sex 是否存在
if 'Sex' in dict:
    print("键 Sex 存在")
else:
    print("键 Sex 不存在")

# not in

# 检测键 Name 是否存在
if 'Name' not in dict:
    print("键 Name 不存在")
else:
    print("键 Name 存在")

以上结果输出为:

键 Age 存在
键 Sex 不存在
键 Name 存在

dict.items()

item() 方法以列表返回可遍历的(键, 值) 元组数组

dict = &#123;'Name': 'Mary', 'Age': 17&#125;
 
print ("Value : %s" %  dict.items())

# 输出结果为:
Value : dict_items([('Age', 17), ('Name', 'Mary')])

可遍历的元组数组举例:

dict1 = &#123;'老大':'25岁',
        '老二':'20岁',
        '老三':'12岁',
        &#125;
print(dict1.items())
for key,values in dict1.items():
    print(key + '已经' + values + '了')

以上结果输出为:

老大已经25岁了
老二已经20岁了
老三已经12岁了

Process finished with exit code 0

dict..keys()

返回一个迭代器,可以使用 list() 来转换为列表

keys()方法语法:

dict.keys()

实例:

dict = &#123;'Name': 'Mary', 'Age': 17&#125;
print(dict.keys())

以上结果输出为:

dict_keys(['Name', 'Age'])

由结果看出结果返回一个迭代对象,可以使用 list 转换为列表:

list1 = list(dict.keys())
print ("转换后的结果为 : %s" % list1)

# 输出结果为一个列表,后续可以对其进行相应操作:
转换后的结果为 : ['Name', 'Age']

dict..setdefault()

Python 字典 setdefault() 方法和 get() 方法类似, 如果 key 在 字典中,返回对应的值。如果不在字典中,则插入 key 及设置的默认值 default,并返回 default ,default 默认值为 None。

setdefault()方法语法:

dict.setdefault(key, default=None)
# 参数
key -- 查找的键值。
default -- 键不存在时,设置的默认键值。

实例:

dict = &#123;'Name': 'Mary', 'Age': 17&#125;
 
print ("Age 键的值为 : %s" %  dict.setdefault('Age', None))
print ("Sex 键的值为 : %s" %  dict.setdefault('Sex', None))
print ("新字典为:", dict)

以上结果输出为:

Age 键的值为 : 17
Sex 键的值为 : None
新字典为:&#123;'Age': 17, 'Name': 'Mary', 'Sex': None&#125;

dict.update(dict2)

Python 字典 update() 函数把字典参数 dict2 的 key/value(键/值) 对更新到字典 dict 里。

语法:

dict.update(dict2)
# 参数
 dict2 -- 添加到指定字典dict里的字典。

实例:

dict = &#123;'Name': 'Mary', 'Age': 17&#125;
dict2 = &#123;'Sex': 'female' &#125;

# 将 dict2 中的结果添加到字典 dict 中 
dict.update(dict2)
print ("更新字典 dict : ", dict)

以上结果输出为:

更新字典 dict :  &#123;'Name': 'Mary', 'Age': 17, 'Sex': 'female'&#125;

dict.values()

Python 字典 values() 方法返回一个迭代器,可以使用 list() 来转换为列表,列表为字典中的所有值。

dict = &#123; 'Name': 'Mary','Sex': 'male', 'Age': 7&#125;
print("字典所有值为 : ", list(dict.values()))

以上结果输出为:

字典所有值为 :  ['Mary', 'male', 7]

dict.pop(key[,default])

Python 字典 pop() 方法删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。否则,返回default值。

pop()方法语法:

pop(key[,default])
#参数
key: 要删除的键值
default: 如果没有 key,返回 default 值

# 返回值
返回被删除的值。

实例:

dict = &#123;'Name': 'Mary', 'Age': 17&#125;

result = dict.pop('Age') # 删除

print(result)

以上结果输出为:

17
Process finished with exit code 0

dict.popitem()

Python 字典 popitem() 方法随机返回一个键值对(key,value)形式,按照 LIFO(Last In First Out 后进先出法) 顺序规则,即最末尾的键值对。如果字典已经为空,却调用了此方法,就报出KeyError异常。

实例:

dict = &#123;'Name': 'Mary', 'Age': 17&#125;
pop_obj=dict.popitem()
print(pop_obj)
print(dict)

以上结果输出为:

('Age', 17)
&#123;'Name': 'Mary'&#125;

将字典清空:

dict = &#123;'Name': 'Mary', 'Age': 17&#125;
del dict

print(dict.popitem())

结果输出为:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    print(dict.popitem())
TypeError: descriptor 'popitem' of 'dict' object needs an argument

字典和列表

字典和列表差异

列表中的元素表项由于元素通过序列从 0 开始递增存放,所以列表中的表项是排序的,而字典的内容的表项是不排序的,如下例子就很好的说明列表和字典的区别:

list1 = ['zhangsan',23,'BeiJing']
list2 = ['BeiJing','zhangsan',23]
list1 == list2
False
dic1 = &#123;'name':'zhangsan','age':23,'address':'BeiJing'&#125;
dic2 = &#123; 'age':23,'name':'zhangsan','address':'BeiJing'&#125;
dic1 == dic2
True

由以上实例可以看出,当列表元素内容一致,顺序不同再对比内容时匹配不成功,同理字典值匹配成功,说明字典中元素内容不按顺序存放。

集合

Python也包含有 集合 类型。集合是由不重复元素组成的无序的集。它的基本用法包括成员检测和消除重复元素。集合对象也支持像 联合,交集,差集,对称差分等数学运算。

集合结构如下:

set1 = &#123;'hello', 'hello', 'word', 'word'&#125;
set1
# 输出结果实现自动去重
&#123;'hello', 'word'&#125;

集合创建

可以使用大括号 { } 或者 set() 函数创建集合,

创建格式:

parame = &#123;value01,value02,...&#125;
或者
set(value)

注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

# 创建空集合
>>> empty_set = set()
>>> type(empty_set)
  <class 'set'>

# 创建空字典
>>> empty_dict = &#123;&#125;
>>> type(empty_dict)
  <class 'dict'>

集合的基本操作

添加元素

语法格式:

s.add(x)

将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作。

s = set(('hello','world'))
print(s)

# 向集合 s 中添加元素
s.add('!')
print('添加元素后的集合是:%s' % s)

# 输出结果是:
添加元素后的集合是:&#123;'world', '!', 'hello'&#125;

除了 add() 方法可以添加元素外,还有一个方法,也可以添加元素,并且参数可以是列表,元组,字典等,语法格式如下:

s.update( x )

参数 x 可以是一个,也可以是多个,多个参数之间用逗号相隔

# 1)添加列表
s.update([1,3],[2,4])
print('添加元素后的集合是:%s' % s)

# 2)添加元组
s.update(('h', 'j'))
print('添加元素后的集合是:%s' % s)

移除元素

语法格式:

s.remove( x )

将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。

# 将元素 2 从集合中移除
s.remove(2)
print('移除元素 2 后的集合是:%s' % s)

# 如果移除集合中不存在的元素会报异常
# 移除集合中不存在的集合
s.remove('hi')
print('移除元素后的集合是:%s' % s)

# 异常信息
Traceback (most recent call last):
  File "test.py", line 20, in <module>
  s.remove('hi')
  KeyError: 'hi'

此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:

s.discard( x )
>>>thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.discard("Facebook")  # 不存在不会发生错误
>>> print(thisset)
&#123;'Taobao', 'Google', 'Runoob'&#125;

我们也可以设置随机删除集合中的一个元素,语法格式如下:

s.pop()
# 随机删除集合中的一个元素
print(s)

s.pop()

print('移除元素后的集合是:%s' % s)

输出结果:
&#123;1, 3, 4, 'world', '!', 'hello', 'h', 'j'&#125;
移除元素后的集合是:&#123;3, 4, 'world', '!', 'hello', 'h', 'j'&#125;

注意:在交互模式,pop 是删除集合的第一个元素(排序后的集合的第一个元素)。

计算集合元素个数

语法格式:

len(s)

计算集合 s 元素个数。

print('集合 s 的长度是:%s' % len(s))
# 输出结果集合 s 的长度是:7

清空集合

语法格式:

s.clear()

清空集合

s.clear()
print('集合清空后的结果是:%s' % s)

# 输出结果:
集合清空后的结果是:set()

判断元素是否存在

语法格式:

x in s

判断元素 x 是否在集合 s 中,存在返回 True,不存在返回 False。

# 判断元素是否存在
s = &#123;'hello',  'word'&#125;
# 判断元素 hello 是否在集合 s 中

print(hello' in s)

# 输出结果:True

集合运算

集合之间的运算符分别是‘-’、‘|’、‘&’、‘^’ ; 下面以两个集合之间的运算为例进行讲解:

  • ‘-’:代表前者中包含后者中不包含的元素
  • ‘|’:代表两者中全部元素聚在一起去重后的结果
  • ‘&’:两者中都包含的元素
  • ‘^’:不同时包含于两个集合中的元素
>>> a = set('afqwbracadaagfgbrafg')
>>> b = set('rfgfgfalacazamddg')
>>> a                                  
&#123;'r', 'q', 'd', 'b', 'w', 'g', 'f', 'c', 'a'&#125;
>>> b
&#123;'r', 'd', 'g', 'f', 'l', 'z', 'c', 'm', 'a'&#125;
# 集合a中包含而集合b中不包含的元素
>>> a - b                              
&#123;'b', 'w', 'q'&#125;
 # 集合a或b中包含的所有元素
>>> a | b                             
&#123;'d', 'g', 'l', 'c', 'r', 'q', 'b', 'w', 'f', 'z', 'm', 'a'&#125;
# 集合a和b中都包含了的元素
>>> a & b                              
&#123;'r', 'd', 'g', 'f', 'c', 'a'&#125;
# 不同时包含于a和b的元素
>>> a ^ b                              
&#123;'l', 'q', 'b', 'w', 'z', 'm'&#125;

集合推导式

和列表一样,集合也支持推导式

# 判断元素是否存在
>>> a = &#123;x for x in 'abracadabra' if x not in 'abc'&#125;
>>> a
&#123;'r', 'd'&#125;

集合内置方法

difference()

difference() 方法用于返回集合的差集,即返回的集合元素包含在第一个集合中,但不包含在第二个集合(方法的参数)中,返回一个新的集合。 difference() 方法语法:

set.difference(set)

实例: 两个集合的差集返回一个集合,元素包含在集合 x ,但不在集合 y :

# 求两个集合的差集,元素在 x 中不在 y 中
x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "microsoft", "apple"&#125;

z = x.difference(y)

print('两个集合的差集是:%s' % z)

# 输出结果为:
&#123;'cherry', 'banana'&#125;

difference_update()

  • difference_update() 方法用于移除两个集合中都存在的元素。
  • difference_update() 方法与 difference() 方法的区别在于 difference() 方法返回一个移除相同元素的新集合,而 difference_update() 方法是直接在原来的集合中移除元素,没有返回值。
x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "microsoft", "apple"&#125;

x.difference_update(y)

print(x)
结果为:
&#123;'banana', 'cherry'&#125;

x1 = &#123;1,2,3,4&#125;
y1 = &#123;1,2,3&#125;

x1.difference_update(y1)

print(x1)

# 结果为:
&#123;4&#125;

intersection()

intersection() 方法用于返回两个或更多集合中都包含的元素,即交集,返回一个新的集合。

intersection() 方法语法:

set.intersection(set1, set2 ... etc)

**参数:**
set1 -- 必需,要查找相同元素的集合
set2 -- 可选,其他要查找相同元素的集合,可以多个,多个使用逗号 , 隔开

实例:

# 返回两个或者多个集合的交集
x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "apple"&#125;

z = x.intersection(y)

print(z)

# 返回三个集合的交集
x = &#123;"a", "b", "c"&#125;
y = &#123;"c", "d", "e"&#125;
z = &#123;"f", "g", "c"&#125;

result = x.intersection(y, z)
print('三个集合的差集是:%s' % result)

# 输出结果:

&#123;'apple'&#125;
两个集合的差集是:&#123;'c'&#125;

intersection_update()

  • intersection_update() 方法用于获取两个或更多集合中都重叠的元素,即计算交集。
  • intersection_update() 方法不同于 intersection() 方法,因为 intersection() 方法是返回一个新的集合,而 intersection_update() 方法是在原始的集合上移除不重叠的元素。

intersection_update() 方法语法:

set.intersection_update(set1, set2 ... etc)

**参数**
set1 -- 必需,要查找相同元素的集合
set2 -- 可选,其他要查找相同元素的集合,可以使用多个多个,多个使用逗号‘,’ 隔开

实例:

# 返回一个无返回值的集合交集
x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "apple"&#125;

x.intersection_update(y)

print(x)

x = &#123;"a", "b", "c"&#125;
y = &#123;"c", "d", "e"&#125;
z = &#123;"f", "g", "c"&#125;

x.intersection_update(y, z)

print(x)

# 输出结果:
&#123;'apple'&#125;
&#123;'c'&#125;

union()

union() 方法返回两个集合的并集,即包含了所有集合的元素,重复的元素只会出现一次,返回值返回一个新的集合

语法:

union() 方法语法:

set.union(set1, set2...)
参数
set1 -- 必需,合并的目标集合
set2 -- 可选,其他要合并的集合,可以多个,多个使用逗号 , 隔开。

实例:

# 合并两个集合,重复元素只会出现一次:

x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "apple"&#125;
 
z = x.union(y) 
 
print(z)
输出结果为:

&#123;'cherry', 'runoob', 'google', 'banana', 'apple'&#125;

# 合并多个集合:

实例 1
x = &#123;"a", "b", "c"&#125;
y = &#123;"f", "d", "a"&#125;
z = &#123;"c", "d", "e"&#125;
 
result = x.union(y, z) 
 
print(result)
输出结果为:

&#123;'c', 'd', 'f', 'e', 'b', 'a'&#125;

isdisjoint()

isdisjoint() 方法用于判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。

语法:

isdisjoint() 方法语法:

set.isdisjoint(set)

实例:

x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "apple"&#125;
# 判断集合 y 中是否包含集合 x 中的元素,如果没有返回 True, 有则返回 False
z = x.isdisjoint(y)
# 结果返回 False,说明集合 y 中有和 x 中相同的元素
print(z)


x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "baidu"&#125;
# 判断集合 y 中是否包含集合 x 中的元素,如果没有返回 True, 有则返回 False
z = x.isdisjoint(y)
# 结果返回 True,说明集合 y 中没有和 x 中相同的元素
print(z)


输出结果:
False
True

issubset()

issubset() 方法用于判断集合的所有元素是否都包含在指定集合中,如果是则返回 True,否则返回 False。

语法:

issubset() 方法语法:

set.issubset(set)

**参数**
set -- 必需,要比查找的集合
返回值
返回布尔值,如果都包含返回 True,否则返回 False

实例:

# 判断集合 x 的所有元素是否都包含在集合 y 中:
x = &#123;"a", "b", "c"&#125;
y = &#123;"f", "e", "d", "c", "b", "a"&#125;
 
z = x.issubset(y) 
 
print(z)

输出结果
# 说明 集合 x 中的元素都包含在 y 中
True

注意:必须是集合中的元素都包含在内,否则结果为false

# 集合 y 中只有元素 b 和 c ,执行结果为False 
x = &#123;"a", "b", "c"&#125;
y = &#123;"f", "e", "d", "c", "b","y"&#125;

z = x.issubset(y)

print(z)

结果输出;
False

issuperset()

issuperset() 方法用于判断指定集合的所有元素是否都包含在原始的集合中,如果是则返回 True,否则返回 False。

语法:

set.issuperset(set)

实例:

# 判断集合 y 的所有元素是否都包含在集合 x 中:
x = &#123;"f", "e", "d", "c", "b", "a"&#125;
y = &#123;"a", "b", "c"&#125;
 
z = x.issuperset(y) 
 
print(z)
输出结果为:

True


# 如果没有全部包含返回 False:

实例 1
x = &#123;"f", "e", "d", "c", "b"&#125;
y = &#123;"a", "b", "c"&#125;
 
z = x.issuperset(y) 
 
print(z)
输出结果为:

False

symmetric_difference()

symmetric_difference() 方法返回两个集合中不重复的元素集合,即会移除两个集合中都存在的元素,结果返回一个新的集合。

语法:

set.symmetric_difference(set)

实例:

# 返回两个集合组成的新集合,但会移除两个集合的重复元素:
x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "apple"&#125;

z = x.symmetric_difference(y)

print(z)

输出结果:
&#123;'banana', 'google', 'cherry', 'runoob'&#125;

symmetric_difference_update()

symmetric_difference_update() 方法移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。

语法:

set.symmetric_difference_update(set)

实例:

# 在原始集合 x 中移除与 y 集合中的重复元素,并将不重复的元素插入到集合 x 中:
x = &#123;"apple", "banana", "cherry"&#125;
y = &#123;"google", "runoob", "apple"&#125;

x.symmetric_difference_update(y)

print(x)

输出结果:
&#123;'runoob', 'cherry', 'banana', 'google'&#125;

文章作者: WuLiZeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WuLiZeng !
评论
  目录