7.深浅拷贝

1. 基础数据类型补充

首先关于int和str在之前的学习中已经讲了80%以上了. 所以剩下的自己看一看就可以了. 我们补充给⼀一个字符串基本操作 

join()

获取到的每个元素和前面的进行拼接. 得到的是字符串

lst = ["alex","dsb","wusir","xsb"]
s = "_".join(lst)
print(s) #alex_dsb_wusir_xsb

split()

切割的结果是列表

s = "alex_dsb_wusir_xsb"
lst = s.split("_")#列表
print(lst) #['alex', 'dsb', 'wusir', 'xsb']

列表循环删除列表的每一个元素

li = [11,22,33,44]
for e in li:
    li.remove(e)
print(li) #[22,44]

列表和字典: 都不能在循环的时候直接删除
而是把要删除的内容记录在新列表中然后循环这个新列表. 删除列表(字典)

lst = ["篮球","排球","足球","电子竞技","排球"]
new_lst = []
for el in lst:
    if "球" in el:
        new_lst.append(el)
print(new_lst)#['篮球', '排球', '足球', '排球']

for i in new_lst:
    lst.remove(i)
print(lst)#['电子竞技']

报错的代码

dic = {"张无忌":"乾坤大挪移", "周芷若":"哭", "赵敏":"卖萌"}
for k in dic:
    dic.pop(k)  # dictionary changed size during iteration
    dic["灭绝师太"] = "倚天屠龙剑"

运行报错的原因:

     for的运行过程. 会有一个指针来记录当前循环的元素是哪一个, 一开始这个指针指向第0 个. 然后获取到第0个元素. 紧接着删除第0个. 这个时候. 原来是第一个的元素会自动的变成第0个. 然后指针向后移动一次, 指向1元素.  这时原来的1已经变成了0, 也就不会被删除了.   

fromkeys()

把第一个参数进行迭代. 拿到每一项作为key和后面的value组合成字典

坑1: 返回新字典. 不会更改老字典

dic = {}
d = dic.fromkeys("风扇哥", "很困")
print(dic) # {}
print(d)#{'风': '很困', '扇': '很困', '哥': '很困'}

坑2: 当value是可变的数据类型. 各个key共享同一个可变的数据类型. 其中一个被改变了. 其他都跟着变

d = dict.fromkeys("胡辣汤", [])
print(d) # {'胡': [], '辣': [], '汤': []}
print(id(d['胡']))#2679822994120
print(id(d['辣']))#2679822994120
print(id(d['汤']))#2679822994120

d['胡'].append("河南特色")
print(d)  # {'胡': ['河南特色'], '辣': ['河南特色'], '汤': ['河南特色']}

# 程序员找工作和菜市场大妈买白菜是一样的

dict中的元素在迭代过程中是不允许进行删除的

dic = {"k1":"alex",'k2':'wusir','s1':'金老板'}
# 删除key带'k'的元素
for k in dic:
    if 'k' in k:
        del dic[k] #dictionary changed size during iteration
# 代的时候不允许进行删除操作
print(dic)

那怎么办呢? 把要删除的元素暂时先保存在一个list中, 然后循环list, 再删除 

dic = {"k1":"alex",'k2':'wusir','s1':'金老板'}
dic_new = []
# 删除key带'k'的元素
for k in dic:
    if 'k' in k:
        dic_new.append(k)

for el in dic_new:
    del dic[el]
print(dic)

类型转换:

元组=>列表 list(tuple)

列表 =>元组 tuple(list)

list =>str  str.join(list)

str =>list  str.split()  

转换成False的数据:

0,' ',,None,[],{},set() ==>False

set集合

set集合是python的一个基本数据类型. 一般不是很常用. set中的元素是不重复的.无序的.里面的元素必须是可hash的(int, str, tuple,bool), 我们可以这样来记. set就是dict类型的数据但是不保存value, 只保存key. set也用{}表示

注意: set集合中的元素必须是可hash的, 但是set本身是不可hash得. set是可变的

set1 = {'1','alex',2,True,[1,2,3]}# 报错list
set2 = {'1','alex',2,True,{1:2}}# 报错dict
set3 = {'1','alex',2,True,(1,2,[2,3,4])}  # 报错list

set中的元素是不重复的, 且无序的. 

s = {"周杰伦","周杰伦","周星驰"}
print(s) #{'周星驰', '周杰伦'}

用这个特性.我们可以使用set来去掉重复 

lst = [45,5,"哈哈",45,"哈哈",50]
lst = list(set(lst)) # 把list转换成set, 然后再转换回list 
print(lst)#[5, 50, '哈哈', 45]

set集合的增删改查

1.增加

s = {'alex','wusir','小钱'}
s.add('太白')
print(s)#{'wusir', '小钱', '太白', 'alex'}
s.add("小钱") #重复的内容不会添加到set集合
print(s)#{'wusir', '小钱', '太白', 'alex'}

s = {'alex','wusir','小钱'}
s.update("太白") #迭代更新
print(s)#{'alex', 'wusir', '白', '小钱', '太'}
s.update(["成龙","吴斌","张智成"])
print(s)#'alex', '张智成', 'wusir', '白', '小钱', '太', '吴斌', '成龙'}

2.删除

s = {'alex','wusir','小钱',"成龙","吴斌"}
item = s.pop()#随机弹出一个
print(s)#{'吴斌', 'alex', '小钱', '成龙'}
print(item)#wusir

s.remove("吴斌")
print(s)#{'小钱', '成龙', 'alex', 'wusir'}
s.remove("sb") #不存在这个元素,删除会报错

s.clear()# #清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和dict区分的. 
print(s) #set()

3.修改

# set集合中的数据没有索引. 也没有办法去定位一个元素. 所以没有办法进行直接修改.
#  我们可以采用先删除后添加的方式来完成修改操作
s = {'alex','wusir','小钱',"成龙","吴斌"}
s.remove("小钱")
s.add("张智成")
print(s)

4.查询

# set是一个可迭代对象. 所以可以进行for循环 
for el in s:
    print(el)

5.常用操作

s1 = {"刘能", "赵四", "皮长山"}
s2 = {"刘科长", "冯乡长", "皮长山"}
# 交集
#  两个集合中的共有元素
print(s1 & s2)  #{'皮长山'}
print(s1.intersection(s2))#{'皮长山'}
#并集
print(s1 | s2) #{'皮长山', '刘科长', '刘能', '冯乡长', '赵四'
print(s1.union(s2)) #{'冯乡长', '皮长山', '刘科长', '赵四', '刘能'}
#差集
print(s1 - s2)#{'刘能', '赵四'}
print(s1.difference(s2))#{'刘能', '赵四'}
#反交集
print(s1^s2)#{'赵四', '刘能', '冯乡长', '刘科长'}
print(s1.symmetric_difference(s2))#{'赵四', '刘能', '冯乡长', '刘科长'}
#子集
s1 = {"刘能", "赵四"}
s2 = {"刘能", "赵四", "皮长山"}
print(s1<s2)#True
print(s1.intersection(s2))#{'刘能', '赵四'}
#超集
print(s1>s2)#False
print(s1.issuperset(s2))#False

set集合本身是可以发生改变的. 是不可hash的. 我们可以使用frozenset来保存数据. frozenset是不可变的. 也就是一个可哈希的数据类型 

s = frozenset(["赵本山", "刘能", "皮长山", "⻓长跪"])
dic = {s:"123"}
print(dic) #{frozenset({'刘能', '长跪', '皮长山', '赵本山'}): '123'}

不是很长用,了解   

2. 深浅拷贝(重点, 难点)

1. = 没有创建新对象, 只是把内存地址进行了复制

lst1 = ["胡辣汤","灌汤包","油泼面","麻辣香锅",["长白山","白洋淀"]]
lst2  = lst1
print(id(lst1))#2716046999880
print(id(lst2))#2716046999880

print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]
print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]

lst1.append("葫芦娃")
print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀'], '葫芦娃']
print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀'], '葫芦娃']

对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制一份内容. 所以lst1的内存指向和lst2是一样的. lst1改变了, lst2也发生了改变

2. 浅拷贝 .copy() 只拷贝第一层.

lst1 = ["胡辣汤","灌汤包","油泼面","麻辣香锅",["长白山","白洋淀"]]
lst2 = lst1.copy()
print(id(lst1))#2716046999816
print(id(lst2))#2716046999688

print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]
print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]

lst1[4].append("葫芦娃")
print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀', '葫芦娃']]
print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀', '葫芦娃']]

3. 深拷贝
import copy
copy.deepcopy() 会把对象内部的所有内容进行拷贝

import copy
lst1 = ["胡辣汤","灌汤包","油泼面","麻辣香锅",["长白山","白洋淀"]]
lst2  = copy.deepcopy(lst1)
print(id(lst1))#2814635261768
print(id(lst2))#2814635360520

print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]
print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]

lst1.append("葫芦娃")
print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀'], '葫芦娃']
print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]

都不一样了. 深度拷贝. 把元素内部的元素完全进行拷贝复制. 不会产生一个改变另一个跟着改变的问题

一. 昨日内容回顾
    小数据池
        针对的数据类型: int, str, bool
        小数据池可以帮我们缓存一个对象.
        当重复使用的时候可以快速的响应. 直接把对象返回.
        优点: 快速拿到对象, 节省内存
        缺点: 当小数据池中的内容太多的时候. 程序响应速度是很慢的.
    is和==
        is 比较的是内存地址.
        == 比较的是内容

    encode() : 可以帮我们把字符串转换成bytes类型
    decode() : 把bytes类型还原回字符串类型

    bytes是字节. 是python中最小的数据单元

二. 作业讲解

三. 今日主要内容
    1. 基础数据类型补充
        大多数的基本数据类型的知识.已经学完了
        join()
        "*".join("马虎疼") # 马*虎*疼 把传递进去的参数进行迭代. 获取到的每个元素和前面的*进行拼接. 得到的是字符串
        split() 切割. 切割的结果是列表

        列表和字典: 都不能在循环的时候直接删除
        把要删除的内容记录在新列表中然后循环这个新列表. 删除列表(字典)

        fromkeys()
        坑1: 返回新字典. 不会更改老字典
        坑2: 当value是可变的数据类型. 各个key共享同一个可变的数据类型. 其中一个被改变了. 其他都跟着变

        # 程序员找工作和菜市场大妈买白菜是一样的


    2. 深浅拷贝(重点, 难点)
        1. = 没有创建新对象, 只是把内存地址进行了复制
        2. 浅拷贝  lst.copy() 只拷贝第一层.
        3. 深拷贝
            import copy
            copy.deepcopy() 会把对象内部的所有内容进行拷贝

    预习:
        文件操作(本身简单, 联合其他知识进行操作. 会很烦)
        open()

        read
        write
        append
大概内容

 面试题

a = [1,2]
a[1] = a
print(a[1])

答案

[1,[...]]  

 

作业

7.水仙花,部门税作业

posted @ 2019-02-24 14:21  等待の喵  阅读(372)  评论(0编辑  收藏  举报