第三章 python的数据类型(下)

Posted py-xiaoqiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第三章 python的数据类型(下)相关的知识,希望对你有一定的参考价值。

上一篇我们介绍了一些基础的数据类型和方法。
在这篇里,我们来了解下python特有的数据类型及其方法。

3.4 列表(list)

列表可以存储多个数据,有点类似于powershell里的数组

字符串也可以看做是一个列表

names = ["name1","name2","name3"]  # 有点像数组

print(names[0])  # 可以用下标来调用

3.4.1 列表的特点(有序,可变)

列表有以下特点

  1. 可以存放多个值。(值也可以是列表,元组等)
  2. 有序:从左到右顺序,索引从0开始。
  3. 可变:可修改指定索引位置对应的值。
  4. 容量大:内存有多大就能存多少,类似于python3的int型。

3.4.2 列表的方法

以下分用途(增删改查)介绍列表的方法:

1. 增加:append,insert,extend

append,insert,extend都不返回结果,会返回None

  1. .append(self,object) 追加:将object插到列表最后并且直接赋值给列表

  2. .insert(self,index,object) 插入:将object插入到index的位置,并且直接赋值给列表

  3. .extend(self,iterable) 合并(扩展):将原列表与iterable(列表) 合并,并且直接赋值给原列表
s = [1, 2, 3, 4]
b = [1,2,3,4]

s.extend(b)  # 这里直接把合并后的列表赋值给s
print(S)

2. 删除: del,pop,remove,clear
  1. del 删除:python的通用方法
del list1  # 删除整个列表
del list2[2]  # 删除一个元素
  1. .remove(self, object) 删除第一个匹配的元素(从左到右找),如果不存在就报错
s = ['a', 'b', 'c', 'd']
s.remove('c')
print(s)

s.remove('e')  # 报错:ValueError
  1. .pop(self, index) 弹出:删除并返回元素
list1.pop(3)  # 删除并返回索引指定的元素
list1.pop()  # 删除并返回最后一个元素
  1. .clear(self) 清空列表

3. 修改(赋值): =

可以直接用‘=‘赋值
list01[2] = "name250"

4. 查询:index,count,in,len
  • .index(self,object,start,stop) 返回 从左开始匹配到的第一个object的索引,可以设置开始和结束位置。

    如果查找元素不存在,报错ValueError

s = ['a', 'b', 'c', 'd']
print(s.index('c'))
print(s.index('c', 0, 2))  # 范围中没有'c',报错
  • .count(self, object) 返回 object的个数。
s = ['a', 'b', 'c', 'd']
print(s.count('c'))  # 有1个'c',返回1
print(s.count('e'))  # 没有'e',返回0
  • in / not in 运算符判断是否包含
s = ['a', 'b', 'c', 'd']
print('a' in s)
  • len(o) 返回 o 的长度
s = ['a', 'b', 'c', 'd']
print(len(s))
5. 其他函数 reverse,sort
  • .reverse()
    把列表中的元素反转,也可以用list1[::-1]来实现
s = ['a', 'b', 'c', 'd']
a = ['a', 'b', 'c', 'd']
print(id(s), id(a))  # 显示s和a的内存地址

s.reverse()  # 反转s内元素

a1 = a[::-1]  # 拷贝一份反转了的a给a1

print(s, a1)  #输出一样
print(id(s), id(a1))  # 两种实现方式的区别:s地址不变,a1地址和a不同
  • .sort(self, key, reverse) 把列表的元素排序并且赋值给列表,只能sort同种类型数据(内部使用的是比较运算符)
s = ['a', 'd', 'b', 'c', 5, 7, 3]
s.sort()  # 数据类型不同,报错:TypeError: '<' not supported between instances of 'int' and 'str'

s = ['a', 'd', 'b', 'c']

s.sort()
print(s)

s.sort(reverse=True)  # reverse = False 升序(默认),reverse = True 降序
print(s)

当元素是元组等多值数据类型的时候,可以使用key来指定以哪个元素为标准

def takeSecond(elem):
    return elem[1]
 
# 列表
s = [(2, 2), (3, 4), (4, 1), (1, 3)]
 
# 指定第二个元素排序
s.sort(key=takeSecond)
 
# 输出类别
print(s)

3.4.3 列表的切片(顾头不顾尾)

列表切片就是截取列表的一部分(截取后的列表是一个拷贝)

可以切片的数据类型:列表(list),元组(tuple),字符串(str)。

拷贝:在内存的别的地方再建一份数据

list1[start:end:step]


  • 切片方法:
    • start是开始索引,end其实是从扣掉元素的开始索引(从end开始全切掉)
    • end使用负数,-2 就是扣掉倒数2个
    • 不写end就是从start开始后面全取
    • 不写start就是取到end为止的所有元素
    • step设为负数可以从后往前取(即倒着切)
list1 = ["0","1","2","3","4","5","6"]

print(list1[3:4]) # 从索引3开始取,索引4开始切掉不要:结果只剩下索引3的元素["3"]
print(list1[3:-2])  # -2表示倒数第2个,也就是从倒数第2个往后切掉不要:结果["3","4"]
print(list1[1:])  # 从索引1开始到最后
print(list1[:3])  # 从开始到索引2,索引3开始切掉不要
print(list1[-4:-2])  # 从倒数第4个开始取,倒数第二个开始往后切掉不要
print(list1[1:5:2])  # 从索引1开始,隔1(步长-1)个取1个,索引5开始切掉不要
print(list1[-2:-4:-1])  # 从倒数第2个开始从后往前取,从倒数第4个开始切掉不要:结果["5","4"]

执行结果:

['3']
['3', '4']
['1', '2', '3', '4', '5', '6']
['0', '1', '2']
['3', '4']
['1', '3']
['5', '4']

  • 切片的特殊用法

列表反转(类似reverse()),字符串反转

print(list1[::-1])  # 把列表反转过来(拷贝)
# 因为字符串也可以看做是一个列表(但是不可变),所以也可以用来**反转字符串**

列表拷贝

list2 = list1[:]  # 把list1的拷贝赋值给list2

插入赋值

list1 = [1,2,3,4,5,6,7,8,9,0]
list1[1:6] = 'abcdefghijk'  # 先把1-5切掉,然后把'abcdefghijk'的元素插进去。
# 切掉的位数和插入的位数没有直接关系,只是插入这个切掉的空间罢了。这可能导致插入后,后面的索引发生变化。
# list1[1] = 'abc' 是单纯的列表赋值,不要搞错了哦
print(list1)

执行结果:

[1, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 7, 8, 9, 0]

3.5 字典(dict)

字典定义用,取值的时候用[]

3.5.1 字典的特点(无序,key唯一,key不可变类型,查询速度快)

字典有以下特点:

  1. 只有key没有索引。key-value 结构
  2. key必须为不可变数据类型(字符串,元组,数字),必须唯一。

    原因:hash运算只能对不可变的类型进行运算:可变的hash就没意义了。
  3. 可存放任意多个value,value可修改,可以不唯一
  4. 无序(因为没有索引)
  5. 查询速度非常快,并且不受dict的大小影响(不管有多少条,查询速度也差不多)

    原因: 字典dict 的key 都是要经过hash 生成一个固定长度的hash值 然后dict会把这些hash值(数字)排序号,放入一个列表里 当查其中一个"元素A"的时候,先把元素A hash一下,生成个数字 再用二分法找到列表里的相应数字就可以了。 ※因此数据的插入就要慢点,hash值得列表要插入后重新排序。

二分法搜索的比较次数: 如果 2**n >= 数据总量,那么 n 次比较就可以找到相应数据

3.5.2 字典的方法

以下分用途(增删改查)介绍列表的方法:

1. 创建:直接定义‘‘,dict,fromkeys
  1. 直接定义
    person = "name":"Alex","age":22 # 注意这里用":"来连接key和value

  2. dict()
    person = dict(name="Alex",age=22) # 注意这里用"="来连接key和value ,并且key没有引号

  3. 直接定义 + dict()
    person = dict("name":"Alex","age":22) # 把方法1的定义放在方法2的函数中

  4. fromkeys() 批量生成字典
keys = [0,1,2,3,4,5]
.fromkeys(keys,100)  # 每个key 都赋给 100 的value ,如果不写赋值,value就都是"None"

执行结果:
0: 100, 1: 100, 2: 100, 3: 100, 4: 100, 5: 100

注意:用fromkeys()创建字典,value如果是数组。
在用append给这个数组追加元素的时候,会把给所有key的value都append。
参考

2. 增加: = ,setdefault
  1. 用 ‘=‘ 直接定义
person = "name":"Alex","age":22
person["job"] = "Teacher"  # 如果字典里存在指定的key,就会覆盖原有的value`

注意:如果是存在的key,就会覆盖原有的value

  1. .setdefault(self, k, default) 添加key和value(default),并且返回value。如果是存在的key,不会覆盖原有的value。
person = "name":"Alex","age":22
person.setdefault("salary",[1,2,3])  # 添加key和value,并且返回value`

比较安全的方法,不会覆盖原有值

3. 删除: del,pop,popitem,clear
  1. del 删除:python的通用方法
person = "name":"Alex","age":22  # 创建字典
del person["name"]  # 删除指定key,value
del person  # 删除字典
  1. .pop(self, k) 弹出:删除并返回指定key的value,如果不指定则会报错。
person = dict(name="Alex",age=22)  # 创建字典

print(person.pop("name"))  # 弹出name,并返回'Alex'
#输出: 'Alex'

person.pop()  # 报错:必须指定参数
  1. .popitem(self) 随机弹出: 删除并返回随机一个元素,并以元组(key,value)的形式返回。空字典会报错(KeyError)
person = dict(name="Alex",age=22)  # 创建字典

print(person.pop('name'))  # 弹出
item1 = person.popitem()  # 取得返回的结果
print(type(item1))  # 打印返回结果的类型:tuple
print(person.popitem())  # 弹出
print(person.popitem())  # 报错:KeyError
  1. .clear() 清空字典
person = dict(name="Alex",age=22)  # 创建字典

person.clear()  # 清空
4. 修改: = ,update
  1. 用 ‘=‘ 赋值修改
person = "name":"Alex","age":22
person["name"] = "aaaa"  # 修改name的Alex->aaaa
  1. .update(self, __m, kwagrs)
    更新(合并):合并两个字典,如果有相同的key,则覆盖原来的value。
dict1 = dict(name="aaaa",age=22) 
dict2 = dict(a="bbbb",age=23)

dict1.update(dict2)  #  #如果有重复的key,dict1的值会被dict2的值覆盖 (用dict2来更新dict1)
print(dict1)
5. 查询: get,keys,values,items
  1. .get(self, k) 取得指定k的value。如果不存在,返回default指定的值(默认是None)
dict1 = dict(name="Alex",age=22) 

print(dict1.get('name'))  # 返回'Alex'
print(dict1.get('aaaa'))  # 'aaaa'不存在,返回None
print(dict1.get('aaaa', 'lalalala'))  # 'aaaa'不存在,返回'lalalala'
# 最后一行也可以写成:
# print(dict1.get(k='aaaa', default='lalalala'))

执行结果:

Alex
None
lalalala
  1. .keys(self) 返回 所有的keys(dict_keys类型)

  2. .values(self) 返回 所有的values(dict_values类型)

  3. .items(self) 返回 所有items(dict_items类型)
dict1 = dict(name="Alex",age=22) 

k = dict1.keys()
v = dict1.values()
i = dict1.items()

print(k, v, i)
print(type(k), type(v), type(i))

# print(k[0])  # 因为不是列表类型,会报错:TypeError
# print(v[0])  # 因为不是列表类型,会报错:TypeError
# print(i[0])  # 因为不是列表类型,会报错:TypeError

for k_ in k:  # 可以用for来访问
    print(k_)

执行结果:

dict_keys(['name', 'age'])
dict_values(['Alex', 22])
dict_items([('name', 'Alex'), ('age', 22)])
<class 'dict_keys'> <class 'dict_values'> <class 'dict_items'>
name
age

扩展知识

person = dict(name="Alex",age=22)  # 定义一个字典

# 方式1 官方推荐,效率最高

for i in person:
    print(i)  # 只会输出key
    print(i,person[i]  # 这样会打印key和value

# 方式2 
for i in person.keys():

# 方式3.1
for i in person.items():                
    print(i)  # 这样会以元组的形式打印出所有(key,vaule)

# 方式3.2
# for可以声明复数个临时变量,不过in后面的变量必须有对应的值

for k,v in person.items():  # 声明两个临时变量分别储存key和value  
    print(k,v)

注意:字典无序,所以不能切片

3.6 元组(tuple)

元组其实就相当于一个只读的列表。

3.6.1 元组的特点(不能修改)

元组的特点类似于列表,唯一区别就是

  • 不能修改,只能查询

    可以切片:因为切片的本质是拷贝,并不是修改

3.6.2 元组的方法

以下分用途(因为只读所以只有:查)介绍列表的方法:

1. 创建: 直接定义‘()‘,tuple
  1. 直接定义
tuple1 = (99,12,32,["name1","name2"],12,43)  # 用()定义
  1. 用tuple()函数转换 >这个方法其他数据类型也有类似的,比如int(),str()等。
list1 = ['a', 'b', 'c', 'd']
str1 = 'abcde'
tuple1 = tuple(list1)
tuple2 = tuple(str1)

print(tuple1)
print(tuple2)

执行结果:

('a', 'b', 'c', 'd')
('a', 'b', 'c', 'd', 'e')
当元组里的元素只有一个的时候,不会被视为元组。
a = ('aaa')
print(a,type(a))  # 结果是str型
# 正确的定义方法
a = ('aaa',)  # 加个,就是元组了
2. 查询: count,index,in,len

元组的查询和列表相同,参考3.4.2

3.6.3 元组中的可变数据类型

如果元组中包含可变数据类型的元素,那么这些元素可以修改: 比如包含一个列表。

为什么呢?:因为元组里保存的是各个元素的内存地址,如果元素是另一个容器(比如列表),容器内的内容并不能管理

data = (99,12,32,["name1","name2"],12,43)
data[3][0] = "Alex"
print(data)

执行结果: (99, 12, 32, [‘Alex‘, ‘name2‘], 12, 43)

3.7 集合(set)

集合是个很有特点的数据类型。

3.7.1 集合的特点(元素不可变类型,去重,无序)

集合有以下特点:

  1. 元素必须是不可变数据类型(但是可以增删)

    ··可变数据类型: 列表(list),字典(dict)(key不能变) ··不可变数据类型: 元组(tuple),集合(set),int,float,str --可变数据和不可变数据类型的区别是能否被hash。不可变数据类型能被hash

  2. 天生去重复(集合里没有重复元素)

    定义的时候如果有重复元素,会自动去重

  3. 无序

根据集合的特点,我们经常使用它做

  • 去重复: 但是要注意集合无序
  • 关系运算: 可以取两个集合的交集等

3.7.2 集合的方法

这次我们也以创建,增删改查的顺序罗列方法:

1. 创建: 直接定义‘elems‘,set
  1. 直接定义: set1 = 1,2,3,4,5,‘rain‘,‘alex‘

    注意:我们定义集合的时候不能用set1 = ,因为这样会定义一个字典。 定义空集合,我们用set1 = set()

  2. set()
list1 = ['aaa', 'bbb']
tuple1 = ('ccc', 'ddd')
dict1 = 'a': 1, 'b': 2

set1 = set()
set2 = set(list1)
set3 = set(tuple1)
set4 = set(dict1)  # 只把key放入集合里

print(set1, type(set1))
print(set2)
print(set3)
print(set4)  # 输出key的集合

执行结果:

set() <class 'set'>
'bbb', 'aaa'
'ccc', 'ddd'
'b', 'a'
2. 增加: add
  1. .add(self, element) 往集合里追加元素
set1 = 1,2,3,4,5,'rain','alex'  # 定义

set1.add(5)  # 不报错,因为重复只是不增加元素
set1.add([1,2,3])  # 报错,元素不能被hash -> 原因:可变的数据类型不能被添加
set1.add((1,2,3))  
3. 删除: discard,remove,pop
  1. .discard(self, element)
    删除指定元素
set1 = 1,2,3,4,5,'rain','alex'

set1.discard(5)  # 删除 5 
set1.discard(5)  # 删除不存在的元素不会报错
  1. .remove(self, element) 删除指定元素(指定元素不存在:报错)
set1 = 1,2,3,4,5,'rain','alex'

set1.remove(4)  # 删除 4
set1.remove(4)  # 报错,KeyError
  1. .pop(self)
    弹出:随机(其实是hash值顺序?)删除一个元素,并且返回
set1 = 1, 2, 'rain', 'alex'

print(set1.pop())
print(set1.pop())
print(set1.pop())
print(set1.pop())  
print(set1.pop())  # 报错:对空集合pop报错-KeyError
4. 查询: in,for

用 in 来判断是否包含指定元素 用 for 来遍历元素

集合不能修改,不能切片(因为无序)

3.7.3 集合的关系运算

1. 交集 &

取两个集合的交集并返回。相同于 .intersection()

set1 = 1, 2, 3, 4, 5, 6
set2 = 4, 5, 6, 7, 8, 89, 10

temp_set = set1 & set2
print(temp_set)
2. 合集(并集) |

取两个集合的合集并返回。 相同于 .union()

set1 = 1, 2, 3, 4, 5, 6
set2 = 4, 5, 6, 7, 8, 89, 10

temp_set = set1 | set2
print(temp_set)
3. 差集 -

从被减集合中扣去共有元素并返回。 相同于 .difference()

set1 = 1, 2, 3, 4, 5, 6
set2 = 4, 5, 6, 7, 8, 89, 10

temp_set = set1 - set2    # 从set1 中扣去 set1和set2都有的元素
print(temp_set)
4. 对称差集 ^

取交集以外的元素并返回。相同于 .symmetric_difference()

set1 = 1, 2, 3, 4, 5, 6
set2 = 4, 5, 6, 7, 8, 89, 10

temp_set = set1 ^ set2    # 除了set1和set2共有的元素,其他都保留
print(temp_set)
5. .intersection_update,.difference_update

关系运算并覆盖
交集: .intersection_update()
差集: .difference_update()
set1.difference_update(set2) # 作用是取完差集,并且将结果赋值给set1

6. 集合判断: isdisjoint,issubset
  1. .isdisjoint(self, s)
    判断不相交:不相交返回True

  2. .issubset(self, s)
    判断是子集:左是右的自己返回True

7. 运算符 == < >

运算符只是表示两个集合的包含关系
python3解释器执行 2, 3, 4 >= 2, 3和执行2, 3, 4 > 2, 3的结果为:True,True


3.8 公共功能

  • len() # 数字和bool以外的数据类型都可以用
  • 索引 # 集合不可以索引(无序)
  • 切片 # 列表,元组,字符串
  • 步长 # 列表,元组,字符串
  • for循环 # int,bool以外的全部

以上是关于第三章 python的数据类型(下)的主要内容,如果未能解决你的问题,请参考以下文章

第三章 python的数据类型(上)

Python基础 | Python的组合数据类型

Python学习总结

第三章 Python数据类型

python 用于数据探索的Python代码片段(例如,在数据科学项目中)

第三章 Python数据类型