Python学习2(列表元组字典,集合set)

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习2(列表元组字典,集合set)相关的知识,希望对你有一定的参考价值。

千峰教育在b站的课程,学习笔记

列表list

定义列的格式:[元素1, 元素2, 元素3, …, 元素n]

变量tmp的类型为列表
tmp = [‘xiaoWang’,180, 65.0]
列表中的元素可以是不同类型的
列表切片操作和字符串一样

添加元素

append会把新元素添加到列表末尾
insert(index, object) 在指定位置index前插入元素object
通过extend可以将另一个集合中的元素逐一添加到列表中,也可以通过+号

list1 = ['a','b','c']
list2 = ['d','e']
list1 = list1 + list2
print(list1) #['a', 'b', 'c', 'd', 'e']

删除元素

列表元素的常用删除方法有:

del:根据下标进行删除,或者直接删除整个列表(直接删除变量指针,变量名被垃圾回收了)
pop:删除最后一个元素,或者根据下标删除列表中的元素
remove:根据元素的值进行删除,如果有相同的好几个值,那么只删除从左到右的第一个
clear:清空列表元素(内存没有被释放)

用for循环删除的时候需要注意,删除了元素遍历的下标不会改变,所以可能存在漏删的情况

movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']
print('------删除之前------movieName=%s' % movieName)
del movieName[2]
print('------删除之后------movieName=%s' % movieName)

删除连续相同的元素
如果正常写这样删除,会有问题

list3 = [1,1,3,1,1,5]
for i in list3:
    if i == 1:
        list3.remove(i)

print(list3) # [3, 1, 1, 5]

这个是因为遍历的时候是用下标遍历list3中所有元素,如果删除以后,下标仍然后加1,而列表变小了,所以会跳过连续相同的元素

但是下面这个操作是可行的,因为list3[::]相当于创建了一个新的列表,遍历的并不是list3中的元素,而是新的列表中的元素,而新列表和原列表是相同的,所以这样删除是可行的

list3 = [1,1,3,1,1,5]
for i in list3[::]:
    if i == 1:
        list3.remove(i)

print(list3)

查找

判断是否存在 in、not in
in(存在),如果存在那么结果为true,否则为false
not in(不存在),如果不存在那么结果为true,否则false
index用来查找元素所在的位置,如果未找到则会报错;
count用来计算某个元素出现的次数。
它们的使用和字符串里的使用效果一致。

>>> a = ['a', 'b', 'c', 'a', 'b']
>>> a.index('a', 1, 3) # 注意是左闭右开区间
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'a' is not in list
>>> a.index('a', 1, 4)
3
>>> a.count('b')
2
>>> a.count('d')
0

修改

直接用下标改就可以

排序翻转

sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小。
reverse方法是将list逆置。

交换两个变量值

除了使用第三个中间变量以外,python中可以直接使用下面方法交换
a,b = b,a

列表推导式

所谓的列表推导式,就是指的轻量级循环创建列表

基本方式

a = [x for x in range(3,6)]
# [3, 4, 5]

在循环中使用if

a = [x for x in range(9) if x % 2]
# [1, 3, 5, 7]

# 使用if和列表推导式的结合
list1 = ['hello', 'hi', 'too','high','88']
list2 = [word.title() if word.startswith('h') else word.upper() for word in list1]
print(list2) # ['Hello', 'Hi', 'TOO', 'High', '88']

使用多个for循环创建

a = [(x,y,z) for x in range(1,3) for y in range(2) for z in range(3)]
# [(1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2)]

a = [x for x in range(1,101)]
b = [a[x:x+3] for x in range(0,len(a),3)]
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], ...]

列表的复制

前面也提到过,如果仅仅是用list2 =list1 复制一个列表,仅仅是将list2这个变量的指针指向了list1的内存地址,如果这时候用list2修改列表中内容,list1也会发生改变
即:Python中的赋值运算都是引用(即内存地址)的传递。对于可变类型来说,修改原数据的值,会改变赋值对象的值。

使用列表的copy方法

使用列表的copy方法,可以直接将原来的列表进行复制,变成一个新的列表,这种复制方式是浅拷贝。

nums1 = [1, 5, 8, 9, 10, 12]
nums2 = nums1.copy()  # 调用列表的copy方法,可以复制出一个新的列表

nums2[0] = 100

# 修改新列表里的数据,不会影响到原有列表里的数据
print(nums2)  #  [100, 5, 8, 9, 10, 12]
print(nums1)  #  [1, 5, 8, 9, 10, 12]

copy模块

除了使用列表的copy方法以外,Python还提供了copy模块来复制一个对象。copy模块提供了浅拷贝和深拷贝两种方式,它们的使用方式相同,但是执行的效果有一定的差异。

浅拷贝是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容。
从下面的例子可以看到,仅仅是对最上层的引用进行了拷贝,对最上层的内容进行更改时,并没有将原来words1中的元素进行替换,而在对内层,即第二层列表的元素进行修改时,yes变成了no

import copy

words1 = ['hello', 'good', ['yes', 'ok'], 'bad']

# 浅拷贝只会拷贝最外层的对象,里面的数据不会拷贝,而是直接指向
words2 = copy.copy(words1)

words2[0] = '你好'
words2[2][0] = 'no'

print(words1)  # ['hello', 'good', ['no', 'ok'], 'bad']
# wrods2 里的 yes 被修改成了 no
print(words2)  # ['你好', 'good', ['no', 'ok'], 'bad']

深拷贝是对于一个对象所有层次的递归拷贝。
用deepcopy拷贝是将里面的所有内容都拷贝了,所以对拷贝对象进行修改的时候,不会影响原内容

import copy

words1 = ['hello', 'good', ['yes', 'ok'], 'bad']

# 深拷贝会将对象里的所有数据都进行拷贝
words2 = copy.deepcopy(words1)

words2[0] = '你好'
words2[2][0] = 'no'

print(words1)  # ['hello', 'good', ['yes', 'ok'], 'bad']
print(words2)  # ['你好', 'good', ['no', 'ok'], 'bad']

切片也是一种浅拷贝

words1 = ['hello', 'good', ['yes', 'ok'], 'bad']
words2 = words1[:]
words2[0] = '你好'
words2[2][0] = 'no'
print(words1)  # ['hello', 'good', ['no', 'ok'], 'bad']
print(words2) # ['你好', 'good', ['no', 'ok'], 'bad']

word3 = ['h', 'a']
print(words1)  # ['hello', 'good', ['yes', 'ok'], 'bad']
print(words2) # ['你好', 'good', ['h', 'a'], 'bad']

元组tuple

Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。
访问元组也是直接使用下标就可以了,或者使用切片
查找元素,index和count
不能进行增、删、改

特别注意:定义只有一个元素的元组,需要在唯一的元素后写一个逗号

>>> aTuple = ('et',77,99.9)
>>> aTuple
('et',77,99.9)
# 特别注意
t1 = ()
t2 = ('a')
t3 = ('a',)
print(type(t1))
print(type(t2))
print(type(t3))

列表和元组的转换

list(t) 将t转换成list
tuple(t) 转换成元组

t3 = ('a','b')
t3 = list(t3)
print(type(t3)) # list
t3 = tuple(t3)
print(type(t3)) # tuple

字典

当存储的数据要动态添加、删除的时候,我们一般使用列表,但是列表有时会遇到一些麻烦。就是在修改元素的时候,需要找到元素的下标才能进行修改
使用字典,用键值对 的形式,对元素进行存储,可以通过直接访问关键字来对元素进行修改,相当于java中的map形式

定义字典的格式:键1:值1, 键2:值2, 键3:值3, …, 键n:值n

info = 'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国上海'
info['name']  # 字典使用键来获取对应的值

键可以使用数字、布尔值、布尔值、元组等不可变数据类型,但是一般习惯使用字符串
每个字典里的key都是唯一的,如果出现了多个key,后面的value会覆盖前一个key对应的value
字典是没有下标或者切片的

查看元素

直接用键查看或者使用get方法,
区别就是使用不存在的key获取对应值,get方法会返回None,而前者会报错;
get可以加默认值

info = 'name':'班长','age':18

print(info['age']) # 获取年龄
# print(info['sex']) # 获取不存在的key,会发生异常

print(info.get('sex')) # 获取不存在的key,获取到空的内容,不会出现异常。输出结果为 None
print(info.get('sex''男'))  # 获取不存在的key, 可以提供一个默认值。输出结果为 男,但是默认值是不会对字典造成修改的

修改元素

直接通过键进行修改

添加元素

如果在使用 变量名[‘键’] = 数据 时,这个“键”在字典中,则覆盖原来的值,即相当于修改元素,不存在,那么就会新增这个元素

删除元素

dict.clear() 清空

dict.pop(key) 根据键进行删除,返回值是键对应的值
dict.popitem() 从后往前删除

d = 'name':'zs','age':'19'
r = d.pop('name')
print(d)
print(r) # zs

d = 'name':'zs','age':'19'
r = d.popitem()
print(d)  # 'name': 'zs'
print(r)  # ('age', '19')

del和pop一样,也可以根据key删除,也可以将整个字典删除,会将变量也删除

遍历

for…in…直接遍历,返回的是key

info = 'name':'班长','age':18, 'sex':'man'
for d in info:
    print(d)
#####输出
name
age
sex

获取value,dict.values,输出是一个特殊的列表

print(info.values())
#输出: dict_values(['班长', 18, 'man'])

获取key,dict.keys

print(info.keys())
# dict_keys(['name', 'age', 'sex'])

获取字典中每一项,dict.items,输出是列表套元组的结构

print(info.items())
# 输出:dict_items([('name', '班长'), ('age', 18), ('sex', 'man')])

for k, v in info.items():
    print('key:,value:'.format(k, v))
## 输出
key:name,value:班长
key:age,value:18
key:sex,value:man

setdefault,update,fromkeys

setdefault类似于添加,不常用,只能做添加,不能做修改
update可以将两个字典合并

info.setdefault('a','b')
print(info)
# 'name': '班长', 'age': 18, 'sex': 'man', 'a': 'b'

dict2 = 'a':10
info.update(dict2)
print(info)  # 'name': '班长', 'age': 18, 'sex': 'man', 'a': 10
print(dict2) # 'a': 10

fromkeys创建一个新的字典,用类直接调用,传递的参数是一个可迭代的对象
输出是一个创建的新的字典,其中key是传递的第一个参数列表中的值,value是第二个传递的参数
不常用

dict3 = dict.fromkeys(['a','b'],[10,20])
print(dict3) # 'a': [10, 20], 'b': [10, 20]

集合set

集合(set)是一个无序的不重复元素序列,可以使用大括号 或者 set() 函数创建集合。

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

创建格式:

parame = value01,value02,...
或者
set(value)

添加元素

set.add(x)
或者
s.update(x),可以添加元素,且参数可以是列表,元组,字典等

>>>set1 = set(("Google", "Runoob", "Taobao"))
>>> set1.update(1,3)
>>> print(set1)
1, 3, 'Google', 'Taobao', 'Runoob'
>>> set1.update([1,4],[5,6])  
>>> print(set1)
1, 3, 4, 5, 6, 'Google', 'Taobao', 'Runoob'

删除元素

s.remove(x)
如果删除不存在的,会报错

thisset = set(("Google", "Runoob", "Taobao"))
thisset.remove("Taobao")
print(thisset)
# 'Google', 'Runoob'
thisset.remove("Facebook")   # 不存在会发生错误
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Facebook'

s.discard(x)也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:

thisset = set(("Google", "Runoob", "Taobao"))
thisset.discard("Facebook")  # 不存在不会发生错误
print(thisset)
# 'Taobao', 'Google', 'Runoob'

del可以直接删除这个集合,删除以后变量也不存在了
clear清空,仍然可以重新添加元素

set.pop() 随机删除集合中的任一元素

交集并集差集

可以用方法,也可以用符号

a = 1,2,3,4,5
b = 4,5,6,7,8,9
print(a.intersection(b)) # 4, 5
print(a & b)
print(a.union(b)) # 1, 2, 3, 4, 5, 6, 7, 8, 9
print(a|b)
print(a.difference(b)) # 1, 2, 3
print(a- b)

其它补充

类型转换

list–> tuple、set(长度可能转变)
tuple–>set、list
set–>tuple、list

字典转列表、元组、集合,只是转换键

info = 'name': '班长', 'age': 18, 'sex': 'man'
print(list(info)) # ['name', 'age', 'sex']
print(tuple(info)) # ('name', 'age', 'sex')

列表、元组、集合一般不能转换为字典
特殊情况下可以转

list2 = [[1,2],[3,4]]
print(dict(list2))  # 1: 2, 3: 4

带下标的遍历

可迭代对象都可以使用 enumerate 内置类进行包装成一个 enumerate 对象。对enumerate进行遍历,可以同时得到一个可迭代对象的下标和元素

nums = [12, 9, 8, 5, 4, 7, 3, 6]

# 将列表 nums 包装成 enumerate 对象
for i, num in enumerate(nums): # i表示元素下标,num表示列表里的元素
    print('第%d个元素是%d' % (i, num))

针对可迭代对象的算数运算符

格式化输出

除了使用format,也可以使用如下形式:
python的print字符串前面加f表示格式化字符串,加f后可以在字符串里面使用用花括号括起来的变量和表达式,如果字符串里面没有表达式,那么前面加不加f输出应该都一样.
格式化的字符串文字前缀为’f’和接受的格式字符串相似str.format()。它们包含由花括号包围的替换区域。替换字段是表达式,在运行时进行评估,然后使用format()协议进行格式化。

特别注意内外引号要有区别

info = 'name': '班长', 'age': 18, 'sex': 'man'
print(f"name:info['name']") # name:班长

公共方法

print() input() type() id() len()
bin() oct() hex()
chr() 给ascill码转字符
ord() 给字符转ascill码
max() min() sum() abs()
sorted() 可以给可迭代对象排序,返回一个列表,通过reverse=True变成降序

以上是关于Python学习2(列表元组字典,集合set)的主要内容,如果未能解决你的问题,请参考以下文章

Python列表(list)、元祖(tuple)、集合(set),和字典(dictionary)区别和联系

Python列表元组集合字典的区别和相互转换

Python入门基础学习四

python列表,元组,字典,集合的比较总结

python基础-列表 元组 集合 字典区别和用法

Python列表元组集合字典的区别和相互转换