day07-列表补充(深浅copy),元组类型和字典类型的运用

今日内容:列表补充 元组类型 字典类型

列表之深浅copy

深浅copy介绍

拷贝就是copy,也就是复制的意思。
深浅拷贝顾名思义就存在深拷贝和浅拷贝两种情况。

b = ['zz', 'yy']

a = [1, 2, 3, 4, b]

浅拷贝:

a.copy() 或者a[:]这样a列表就完成了一次浅拷贝

例如:

list = [1,2,3,4]
new_list = list.copy()  # ===> 这时会浅copy list 列表 返回一个新的列表new_list
new_list1 = list[:]

深拷贝:

import copy
list = [1,2,3,4]
new_list = copy.deepcopy(list)  # ===> 这时会深copy list 列表 返回一个新的列表new_list

这样list列表就完成了一次深拷贝。
浅拷贝list.copy()等价于copy.copy(list)

深拷贝和浅拷贝的区别

浅拷贝只拷贝第一层的即l列表的存储数据地址,如果此时b列表(子列表)发生了修改,则new_l列表中b列表的数据也会发生变化,此时数据复制的结果就会不准确.

浅copy的原理图

img

案例:

l = [11, 22, ['xx', 'yy']]
new_l = l.copy()  # t等同于new_l = l[:]
new_l[0] = 00  # 改变的列表对应的元素为11,是一个整型为一个不可变类型的数据,它改变的仅仅是自己,不会影响到原来(关联)的列表

print(l)  # ====> [11, 22, ['xx', 'yy']]
print(new_l)  # ====>[0, 22, ['xx', 'yy']]

new_l[2][1] = 'zzz'  # 此时改变的是列表中的子列表元素['xx', 'yy'] ,子列表是一个列表类型的数据,为一个可变类型,它不仅会改变自己,也会改变原来(关联)的列表
print(l)  # ====> [11, 22, ['xx', 'zzz']]
print(new_l)  # =====> [11, 22, ['xx', 'zzz']]
print(id(l[0]), id(l[1]), id(l[2]))  # ===> 140718605693504 140718605693856 1699776254536
print(id(new_l[0]), id(new_l[1]), id(new_l[2]))  # ===> 140718605693504 140718605693856 1699776254536

总结:浅copy一个列表后,如果copy的列表中的元素有可变类型的数据,当改变其中一个列表中的可变类型对应的值,时俩个值都会受影响.而元素的数据类型为不可变的,则不会影响.

因为声明一个列表的变量时.变量名对应的值是一个索引和索引相对应的元素的值的内存地址,再通过内存地址绑定到索引指向的值,所以当索引指向的值的数据类型为可变的数据类型时,它绑定的值又会延续到下一个索引对应的索引的值的内存地址.也就是说浅copy的元素为可变类型时,它们的子列表的索引对应的内存地址的计数是1,公用一条,

当发生改变时,计数变为0,重新指向同一个内存地址.

为了杜绝这种情况,我们需要进行深拷贝,把进行嵌套的所有列表数据都复制一遍,这样不管哪一层数据发生变化,对我们已经复制的数据都不会产生影响。

深copy底层原理图:

img

深copy会将子列表申请一个新的内存空间,值是一样的.避免改一个而牵连俩个列表.

案例:

from copy import deepcopy
l = [11, 22, ['xx', 'yy']]
new_l1 = deepcopy(l)  # 深copy
print(id(l[0]), id(l[1]), id(l[2]))  # # ===> 140718605693504 140718605693856 1699776254536
print(id(new_l1[0]), id(new_l1[1]), id(new_l1[2]))  # ====> 140718605693504 140718605693856 1699780262472

列表内置方法的补充

需要掌握的

代码中===>后接的是返回结果

l_list = [11, 22, 33, 44, 55, 66, 22, 22, 33]
print(l_list.index(11))  # 列表中的元素对应的索引,返回值是一个索引 ==> 0
print(len(l_list))  # 列表元素的个数 l.__len__()返回值是一个数字 ==> 9

print(l_list.count(33))  # 列表中元素出现的个数 返回值是一个数字  ==> 2
print(l_list.clear())  # 清空一个列表  返回值为None ===> None
print(l_list)  # ===> []
l_list1 = [11, 22, 33, 99, 88, 44, 55, 66, 77]
print(l_list1.extend([77, 88]))  # 往列表中添加多个值(值为一个可迭代对象) 返回的是None
print(l_list1)  # ===> [11, 22, 33, 99, 88, 44, 55, 66, 77, 77, 88]
print(l_list1.reverse())  # 将列表中的元素,反着存放 返回的是None
print(l_list1)  # ===> [88, 77, 77, 66, 55, 44, 88, 99, 33, 22, 11]
print(l_list1.sort())  # 将列表中的元素排序,默认是升序 返回的是None
print(l_list1)  # ===> [11, 22, 33, 44, 55, 66, 77, 77, 88, 88, 99]
print(l_list1.sort(reverse=True))  # 降序 将 reverse=True, 返回的是None
print(l_list1)  # ====> [99, 88, 88, 77, 77, 66, 55, 44, 33, 22, 11]

列表函数(了解)

序号 函数
1 cmp(list1, list2)比较两个列表的元素
2 len(list) 列表元素个数
3 max(list) 返回列表元素最大值
4 min(list)返回列表元素最小值
5 list(seq)将元组转换为列表

元组类型

概念:

  • 元组与列表类似,不同之处在于元组的元素不能修改。
  • 元组使用小括号,列表使用方括号。
  • 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

用途: 元组就相当于一种不可变的列表,所以说元组包含的元素可以是任意类型

作用:存多个值,对比列表来说,元组不可变(是可以当做字典的key的),主要是用来读

定义:与列表类型相似,只不过[]换成()

age=(11,22,33,44,55)  # 本质age=tuple((11,22,33,44,55))

需要注意的是在python中()也可以表示包含的意思,所以,当你使用 i = (1),此时的类型还是整型1
要想存一个1为元组的类型:需要在数字1后面的加上一个","

i1 = (1)
print(i1, type(i1))  # ===> 1 <class 'int'>
i2 = (1,)
print(i2, type(i2))  # ====> (1,) <class 'tuple'>

优先掌握的操作:

提示:详细用法请看前面的列表类型

# 1、按索引取值(正向取+反向取):只能取
t_tuple = (11, 22, 33, 44, 55)
print(t_tuple[0], t_tuple[-1])  # ===> 11 55
# #2、切片(顾头不顾尾,步长)
print(t_tuple[0:2])  # ==> (11, 22)
# #3、长度
print(len(t_tuple))  # ===> 5
# #4、成员运算in和not in
print(11 in t_tuple)  # ===> True

#5、循环
for t in t_tuple:
    print(t)

修改元组

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例

tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')

# tup1[0] = 100 # 这样直接修改元组元素操作是非法的。==> TypeError: 'tuple' object does not support item assignment

# 创建一个新的元组
tup3 = tup1 + tup2
print(tup3)  # ===> (12, 34.56, 'abc', 'xyz')

删除元组

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

del tup1  # 手动释放掉了tup1变量名指向的内存地址,计数为0
print(tup1)  # 再引用会报错 ===>NameError: name 'tup1' is not defined

无关闭分隔符

任意无符号的对象,以逗号隔开,默认为元组,如下实例:

print('abc', 11, 22, 'xyz')  # ===> abc 11 22 xyz
res = 'abc', 11, 11, 'xyz'
print(type(res))  # ===> <class 'tuple'>
x, y = 1, 2
print("Value of x , y : ", x, y)  # ====> Value of x , y :  1 2

字典的数据类型

字典的介绍:

字典是另一种可变容器模型,且可存储任意类型对象。

用途:按照key:value 的方式存放多个值,其中key对value应该有描述性效果

字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:

d = {key1 : value1, key2 : value2 }

键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一。

dict = {'a': 1, 'b': 2, 'b': '3'}
print(dict['b'])  # ===> 3
print(dict)  # ===> {'a': 1, 'b': '3'}

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

小知识点:hash与可变不可变是相反的,即kehash的是不可变数据类型,不可hash的为可变数据类型

数据类型转换

调用字典的dict()方法转成字典的类型有局限性.必须为可迭代对象类型且遍历后有俩个值的

例如:

res = dict([('key', 'value'), ['key1', 'value1']])  # ===> {'key': 'value', 'key1': 'value1'}
print(res)

字典的俩种声明方式

d = {}  # 推荐
print(d, type(d))  # ===> {} <class 'dict'>
d1 = dict()  # 等同于上方的 d = {}
print(d1, type(d1))  # ===> {} <class 'dict'>

如何将变量名绑定一个字典类型的值

语法: dict_obj = {'key1':'value1', 'key2': 'value2'}

案例: 将同学的消息存放在字典中

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}

存了值.我们如何取值

字典中取值的俩种方式:

因为字典是无序的,所以我们不能通过索引取值

按照在dict_obj[key]取对应的value

按照dict_obj.get(key)取对应的value

区别:取一个不存在字典中的key时,按照[key]的方式会报语法错误,而.get(key)的方式会返回一个None

案例: 在同学消息字典中取出他的名字

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
print(student_dict[0])  # ==> KeyError: 0

print(student_dict['name'])  # jkey
print(student_dict.get('name'))  # jkey

当key不存在时

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
# print(student_dict['XXX'])  # 输出 ===> KeyError: 'XXX'
print(student_dict.get('XXX'))  # 输出 ====> None

因为字典是一个可变类型,所以它的值可以改变

改字典的值.

通过dict_obj['key']对相应的value的值进行更改,并且改变原字典

注意:dict_obj.get('key')只能取值,不能该值.

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
student_dict['name'] = 'liu'
print(student_dict)  # 输出 {'name': 'liu', 'age': 18, 'habbyies': ['play', 'eat']}
# student_dict.get('age') = 11  # 该值会报语法错误=== > SyntaxError: can't assign to function call

居然可以改值,是不是也支持添加值呢???

是的.字典可以添加值

字典添加值的操作

因为字典是无序的,并且是以键值对的方式存放,所以我们可以直接通过dict_obj['new_key']=new_value

是不是和改值一样,只不过此时的key是一个原字典不存在的key,"key"最好是唯一的且字符串的类型

案例:往学生字典中添加一个性别的数值

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
student_dict['sex'] = 'male'
print(student_dict)  # 输出 ===>  {'name': 'jkey', 'age': 18, 'habbyies': ['play', 'eat'], 'sex': 'male'}

根据输出结果你可以发现,它是将新的键值对放到字典的最后,这里要提的小知识点是,不管在python2中还是在python3中,字典都是无序的,但是python3中优化了字典的输出.让其看起来像是一个有序的.

那你都可以改了是不是也可以删呢?

是的字典支持删值

方式1:万能删除del

  • 功能:将字典中的变量名和内存地址之间的链接清除,可以是清除一个key:value,也可以是一个字典对象本身
    • 注意:清除了字典对象本身的话,这个变量名就不能被引用了,也就是不能被调用了
  • 语法:
    • del dict_obj或者del dict_obj
  • 没有返回值,用变量名接收还会报错

案例:将学生字典中的name删除

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
del student_dict['name']
print(student_dict) # ===> {'age': 18, 'habbyies': ['play', 'eat']}

del 一个字典对象本身

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
del student_dict
print(student_dict)  # ====>NameError: name 'student_dict' is not defined

方式2: pop()

  • 功能: 删除字典给定键 key 及对应的值
  • 语法:
    • dict_obj.pop(key[,default])
      • key为你要删除的键值对的键--key
      • default:如果没有 key,返回 default 值
  • 返回值为被删除的值。key 值必须给出。 否则,返回 default

案例:将学生字典中的name删除

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
name = student_dict.pop("name")  # 将key=name的键值对在student_dict删除
print(name)  # === > jkey
print(student_dict)  # {'age': 18, 'habbyies': ['play', 'eat']}

方式3: popitem()

  • 功能: 删除一个字典中的最后一个键值对
  • 语法: dict_obj.popitem()
  • 返回的是被删除的最后一个key:value

案例:随机删除学生字典中的一组键值对

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
student_dict.popitem()  # 随机删除student_dict中的一组键值对
print(student_dict)  # === > {'name': 'jkey', 'age': 18}

方式4: clear()

  • 功能:清空字典的键值对
  • 语法:dict_obj.clear()
  • 返回一个None

案例:清空学生字典

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
res = student_dict.clear()  # 清空student_dict
print(student_dict)  # ====> {}
print(res)  # ===> None

是不是感觉干掉字典的方式很多,但字典真正用的多的还是增改查

还有一个很常见的就是和for循环之间的搭配啦

keys()方法

  • 功能: 以列表返回一个字典所有的
  • 语法:
    • dict.keys()
  • 返回值: 返回一个字典所有的

案例:打印出学生字典中所有的键--key

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
for student_key in student_dict.keys():  # 遍历出字典student_dict中的所有的key
    print(student_key)
for s_key in student_dict:
    print(s_key)
    
'''
输出结果是一样的:
        name
        age
        habbies
        name
        age
        habbies
'''

注意:遍历一个字典默认返回的就是字典的键-key

values()方法

  • 功能: 以列表返回字典中的所有值
  • 语法:
    • dict.values()
  • 返回值: 返回字典中的所有值---value

案例:打印出学生字典中的所有的值

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
for s_value in student_dict.values():  # 遍历出字典student_dict中所有的值
    print(s_value)

'''
输出结果为:
        jkey
        18
        ['play', 'eat']
'''

items()方法

  • 功能: 以列表返回可遍历的(键, 值) 元组数组
  • 语法:
  • dict.items()
  • 返回值: 返回可遍历的(键, 值) 元组数组

案例:遍历出学生字典中的键值对

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
for key1, value1 in student_dict.items():  # 遍历student_dict 字典中的 所以键值对,返回(key,value)--->这个元组
    print(key1, value1)
'''
输出结果:
    name jkey
    age 18
    habbies ['play', 'eat']
'''

字典还有其他很多内置函数和方法哦

接着往下看

字典内置方法&函数(补充)

方法

copy()方法

  • 功能: 对一个字典的浅复制
  • 语法:
    • dict.copy()
  • 返回值: 返回一个浅复制过来的字典

案例:将学生字典,浅copy一份出来

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
c_student_dict = student_dict.copy()  # 对学生字典student_dict进行浅copy并绑定给变量名c_student_dict
print(c_student_dict)  # ===> {'name': 'jkey', 'age': 18, 'habbies': ['play', 'eat']}
print(student_dict)  # ===> {'name': 'jkey', 'age': 18, 'habbies': ['play', 'eat']}

深浅copy前面列表有介绍哦

有想深入了解的同学可访问:https://www.runoob.com/w3cnote/python-understanding-dict-copy-shallow-or-deep.html

fromkeys()方法

  • 功能: fromkeys() 函数用于创建一个新字典,以序列seq中元素做字典的键,value 为字典所有键对应的初始值。
  • 语法:
    • dict.fromkeys(seq[, value])
      • seq表示 字典键值列表
      • value -- 可选参数, 设置键序列(seq)的值,一般为None
  • 返回值: 该方法返回一个新字典

案例:创建一个新字典,内容的key为学生消息,值为None

res2 = {}.fromkeys(["name", 'age'], None)
res3 = {}.fromkeys(["name", 'age'], [])
print(res2)  # {'name': None, 'age': None}
print(res3)  # {'name': [], 'age': []}
print(res2['name'])  # None
print(res3['name'])  # []

需要注意的是:如果你将value初始值为一个列表,后面根据key改value会将整个字典全部的key对应的初始列表改变

has_key()方法(了解)

  • 注意:Python 3.X 不支持该方法

  • 功能: 判断键是否存在于字典中,如果键在字典 dict 里返回 true,否则返回 false

  • 语法:

    • dict.has_key(key)
      • key -- 要在字典中查找的键
  • 返回一个布尔值

案例:判断学生字典中的是否有name这个键

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}
print(student_dict.has_key("name"))  # True

setdefault()方法

  • 功能: get()方法 类似, 如果键不存在于字典中,将会添加键并将值设为默认值
  • 语法:
    • dict.setdefault(key, default=None)
      • key 查找的键值
      • default -- 键不存在时,设置的默认键值
  • 返回值: 如果字典中包含有给定键,则返回该键对应的值,否则返回为该键设置的值

案例:判断学生字典中是否有性别(sex)的key,没有就添加,有就不动

student_dict = {'name': 'jkey', 'age': 18,'habbies': ['play','eat']}

# key不存在则添加key:value,key如果存在则什么都不做
# if "sex" not in student_dict:
#     student_dict['sex'] = "male"

student_dict.setdefault("sex", "male")  # 等用于上方的操作
print(student_dict)  # ===> {'name': 'jkey', 'age': 18, 'habbies': ['play', 'eat'], 'sex': 'male'}

update()方法

  • 功能: 把字典dict2的键/值对更新到dict里
  • 语法:
    • dict.update(dict2)
  • 返回值: 该方法没有任何返回值

案例:将水果字典添加到学生字典中

student_dict = {'name': 'jkey', 'age': 18}
goads_dict = {'apple': 2, 'pear': 3, 'peach': 5, 'name': 'liu'}
student_dict.update(goads_dict)  # 将goads_dict的键值对添加到student_dict字典中,没有的键会将键值对直接添加在student_dict最后,如果student_dict字典中有
# 这个key-键 则会根据key-键 更新掉字典中的value
print(student_dict)  # ==> {'name': 'liu', 'age': 18, 'apple': 2, 'pear': 3, 'peach': 5}

函数

序号 函数及描述
1 cmp(dict1, dict2) 比较两个字典元素。
2 len(dict)计算字典元素个数,即键的总数。
3 str(dict) 输出字典可打印的字符串表示。
4 type(variable) 返回输入的变量类型,如果变量

cmp()方法(了解)

  • 在python2所有版本中都可用,但在python3中该函数已经被删掉。

  • 功能:用于比较两个字典元素。

  • 方法语法:cmp(dict1, dict2)

    • dict1 -- 比较的字典
    • dict2 -- 比较的字典

返回值:如果两个字典的元素相同返回0,如果字典dict1大于字典dict2返回1,如果字典dict1小于字典dict2返回-1。

案例:比较字典1和字典2元素大小

dict1 = {'name': 'jkey', 'age': 18}
dict2 = {'name': 'liu', 'age': 22}
print(cmp(dict1,dict2))

len()方法

  • 功能: 计算字典元素个数,即键的总数
  • 语法:
    • len(dict)
      • dict -- 要计算元素个数的字典
  • 返回值: 返回字典的元素个数

案例:打印出学生字典中的键的个数

student_dict = {'name': 'jkey', 'age': 18}
print(len(student_dict))  # ===> 2

str()方法

  • 功能: 将值转化为适于人阅读的形式,以可打印的字符串表示。
  • 语法:
    • str(dict)
  • 返回值: 返回字符串

案例:将学生字典的键值对转换成字符串描述

student_dict = {'name': 'jkey', 'age': 18}
print(str(student_dict))  # ====> {'name': 'jkey', 'age': 18}

type()方法

  • 功能: 返回输入的变量类型,如果变量是字典就返回字典类型。
  • 语法:
    • type(dict)
  • 返回的是一个数据类型

案例:判断student_dict的数据类型

student_dict = {'name': 'jkey', 'age': 18}
print(type(student_dict))  # ===> <class 'dict'>

好啦,大概就这么多了,字典在之后的用处还是很多的,因为我们都知道我们要做的就是对数据的一些存取,字典不仅仅可以存多个值还方便通过key去取值,加油吧!!!!!骚年!!!!

原文地址:https://www.cnblogs.com/jkeykey/p/14180995.html