python之数据类型补充、集合、深浅copy

一、内容回顾
代码块: 一个函数,一个模块,一个类,一个文件,交互模式下,每一行就是一个代码块。
is == id
id()查询对象的内存地址
== 比较的是两边的数值。
is 比较的是两边的内存地址。
小数据池:
前提:int,str,bool
1,节省内存。
2,提高性能和效率。
小数据池是什么?
在内存中,创建一个‘池‘,提前存放了 -5 ~256 的整数,一定规则的字符串和bool值。
后续程序中,如果设置的变量指向的是小数据池的内容,那么就不会再内存中重新创建。

小数据池与代码块的关系。
同一个代码块:python在执行时,遇到了初始化对象命令,他会将这个变量名和数值放到一个字典中,
再次遇到他会从这字典中寻找。
不同代码块:python在执行时,直接从小数据池中寻找,满足条件id相同。
编码:
python3x:

英文:
str: 表现形式:s1 = ‘hello‘
内部编码方式: unicode

bytes:表现形式:s1 = b‘hello‘
内部编码方式: 非unicode
中文:
str: 表现形式:s1 = ‘小白‘
内部编码方式: unicode

bytes:表现形式:s1 = b‘\xe2\xe2\xe2\xe2\xe2\xe2‘
内部编码方式: 非unicode
只有当你想要存储一些内容到文件中,或者通过网络传输时,才要用的bytes类型

str --->bytes: encode
bytes--->str: decode

补充:

s1 = ‘小黑‘
b1 = s1.encode(‘gbk‘)
print(b1)            #gbk的bytes类型

# gbk的bytes类型 -----> utf-8的bytes类型,正常情况是这样转换:
s2 = b1.decode(‘gbk‘)     # 先按照对应的编码方式 解码成字符串(unicode)
b2 = s2.encode(‘utf-8‘)    # 再编码成utf-8的bytes
print(b2)

非中文的字符串还可以这样解码:

s1 = ‘xiaoming‘
b1 = s1.encode(‘gbk‘)     #gbk的bytes类型

s2 = b1.decode(‘utf-8‘)    #可以按照utf-8的形式解码
print(s2)

# 上面代码能成立:因为utf-8 gbk,unicode等编码的英文字母,数字,特殊字符都是映射的ASCII码。

二、基础数据类型补充
1、元组:
如果元组中只有一个数据,且没有逗号,那么该"元组"的数据类型与里面的数据类型一致
否则,该数据类型就是元组

tu1 = (1)
print(tu1,type(tu1))  # 1 <class ‘int‘>

tu1 = (1,)
print(tu1,type(tu1))  # (1,) <class ‘tuple‘>

tu2 = (‘hello‘)
print(tu2,type(tu2))  # hello <class ‘str‘>

tu2 = (‘hello‘,)
print(tu2,type(tu2))  # (‘hello‘,) <class ‘tuple‘>

2、列表:
列表与列表可以相加(就是拼接)
l1 = [1,2,3]
l2 = [‘aa‘,‘bb‘]
l3 = l1 + l2
print(l3) --->[1, 2, 3, ‘aa‘, ‘bb‘]

li = [11, 22, 33, 44, 55, 66, 77, 88]
将列表中索引为奇数的元素,全部删除.
也许刚接触的时候会有人这么写:

li = [11, 22, 33, 44, 55, 66, 77, 88]
# 问题代码1:
for i in li:
    if li.index(i) % 2 == 1:
        li.remove(i)
print(li)

# 问题代码2:
for i in range(len(li)):
    if i % 2 == 1:
        li.pop(i)
print(li)

但是你会发现这样做并不能实现结果,要么报错,要么实现不了预想的结果,为什么呢?
这是因为:在循环一个列表时,如果对列表中的某些元素进行删除,
那么此元素后面的所有元素就会向前进一位,他们的索引和长度就会发生变化。

所以正确的方法可以这样写:

li = [11, 22, 33, 44, 55, 66, 77, 88]
# 方法一:切片+步长删除
del li[1::2]
print(li)

# 方法二:
l2 = []
for i in range(len(li)):
    if i % 2 == 0:
        l2.append(li[i])
li = l2
print(li)

# 方法三:倒着删除
for index in range(len(li)-1, -1, -1):
    if index % 2 == 1:
        li.pop(index)
print(li)

总结:在循环一个列表时,最好不要对此列表进行改变大小(增删)的操作。

3、字典:
创建字典的方式:
(1)直接创建:dic = {‘name‘:‘hello‘,‘age‘:18}
(2)dic = dict({‘name‘:‘hello‘,‘age‘:18})
(3)dic = dict.fromkeys([1,2,3],‘hello‘)      #迭代创建(第一个参数是可迭代对象,str list dict等)
结果: {1: ‘hello‘, 2: ‘hello‘, 3: ‘hello‘}

陷阱:
(1)
dic = dict.fromkeys([1,2,3],‘hello‘)
print(dic)
print(id(dic[1]))
print(id(dic[2]))
print(id(dic[3]))
结果:

{1: ‘hello‘, 2: ‘hello‘, 3: ‘hello‘}
1604999043984
1604999043984
1604999043984

(2)
dic = dict.fromkeys([1,2,3],[])
print(dic)
这样创建的是值为空列表的字典:
{1: [], 2: [], 3: []}

dic[1].append(‘nihao‘)
print(dic)
print(id(dic[1]))
print(id(dic[2]))
print(id(dic[3]))
结果:
{1: [‘nihao‘], 2: [‘nihao‘], 3: [‘nihao‘]}
2347486287880
2347486287880
2347486287880

dic[2].append(‘I am fine‘)
print(dic)
print(id(dic[1]))
print(id(dic[2]))
print(id(dic[3]))
结果:
{1: [‘nihao‘, ‘I am fine‘], 2: [‘nihao‘, ‘I am fine‘], 3: [‘nihao‘, ‘I am fine‘]}

2347486287880
2347486287880
2347486287880

结论:dict.fromkeys()方法迭代创建的字典,迭代的键都是指向同一个内存地址(值相同)

dic = {‘key1‘: ‘value1‘, ‘key2‘: ‘value2‘, ‘k3‘: ‘v3‘, ‘name‘: ‘aaa‘}
# 将dic的键中含有k元素的所有键值对删除。
# 错误代码:
for key in dic:
    if ‘k‘ in key:
        dic.pop(key)
print(dic)
# 这样写会报错dictionarychangedsizeduringiteration
# 这是因为在循环一个字典时,不能改变字典的大小,否则就会报错。

# 正确方法可以:
l1 = []
for key in dic:
    if ‘k‘ in key:
        l1.append(key)
for key in l1:  # 第二次循环的是含有‘k‘的所有键组成的一个列表,并在循环列表的时候删除字典里的键值对
    dic.pop(key)
print(dic)

数据类型的转换。
‘‘‘
int str bool 三者转换
str <---> bytes
str <---> list
dict.keys() dict.values() dict.items() list()
tuple <---> list
dict ---> list
‘‘‘

str ---> list:split()
s1 = ‘aa bb cc‘
l1 = s1.split()
print(l1)

list ---> str:join() 此list中的元素全部是str类型才可以转换
l1 = [‘aa‘, ‘bb‘, ‘cc‘]
s2 = ‘ ‘.join(l1)
print(s2)

list ---> tuple
l1 = [1,2,3]
tu1 = tuple(l1)
print(tu1)

tuple ---> list
tu2 = (0,2,3)
l1 = list(tu2)
print(l1)

dict ---> list
dic1 = {‘name‘: ‘alex‘, ‘age‘: 1000}
l1 = list(dic1)
l2 = list(dic1.keys())
l3 = list(dic1.values())
l4 = list(dic1.items())
print(l1)
print(l2)
print(l3)
print(l4)

三、集合set
set:
{‘aa‘,‘bb‘,1,2,3}
集合要求里面的元素必须是不可变的数据类型但是集合本身是可变的数据类型。
集合里面的元素不重复(天然去重),无序
主要用途:
1,去重。
2,关系测试。

set1 = {‘abc‘, [1,2], 1,2,3}     # 这个是错误的   因为集合要求里面的元素必须是不可变的数据类型,因此这里会报错(列表是可变的数据类型)
set2 = {‘aa‘, ‘bb‘}           #直接定义
set3 = set({‘aa‘, ‘bb‘})    #set()方法
print(set2)

list去重 *****
l1 = [1,1,2,3,4,4,3,2,1,5,5]
set1 = set(l1)        #先把列表转换成集合,自动去重
l2 = list(set1)        #再把集合转换成列表
print(l2)

set1 = {‘hello‘,‘handsome‘,‘boy‘,‘you‘,‘good‘}

set1.add(‘女神‘)
print(set1)

set1.update(‘abc‘)    #update:迭代着增加
print(set1)


set1.remove(‘hello‘) # 删除一个元素
print(set1)

set1.pop() # 随机删除一个元素
print(set1)

set1.clear() # 清空集合
print(set1)

del set1 # 删除集合
print(set1)

关系测试

set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}

交集(& 或者 intersection)
print(set1 & set2)                    # {4, 5}
print(set1.intersection(set2))   # {4, 5}

并集(| 或者 union)
print(set1 | set2)              #{1, 2, 3, 4, 5, 6, 7, 8}
print(set1.union(set2))

反交集(^ 或者 symmetric_difference)
print(set1 ^ set2)                  # {1, 2, 3, 6, 7, 8}
print(set1.symmetric_difference(set2))

差集(- 或者 difference)
print(set1 - set2)            # {1, 2, 3}
print(set1.difference(set2))
print(set2 - set1)           #{8, 6, 7}

子集
set1 = {1,2,3}
set2 = {1,2,3,4,5,6}
print(set1 < set2)      # True
print(set1.issubset(set2))

超集
print(set2 > set1)
print(set2.issuperset(set1))

frozenset不可变集合,让集合变成不可变类型。
set1 = {1,2,3}
set2 = frozenset(set1)
print(set2)                 # 不可变的数据类型。 ***

四、深浅copy
赋值运算
l1 = [1,2,3]
l2 = l1
l1.append(666)
print(l2)
print(id(l1))
print(id(l2))    #是同一个地址,l2 = l1只是把l2指向了l1的地址,l1改变,l2也改变

浅copy(只针对列表,字典,集合):数据(列表)第二层开始可以与原数据进行公用
深copy(引用copy模块,任意数据类型都可深copy):完全独立的copy一份数据,与原数据没有关系

浅copy
l1 = [1,2,3]
l2 = l1.copy()
l1.append(666)
print(l2)                #第一层是独立的:[1, 2, 3]

l1 = [1,2,3,[22,]]
l2 = l1.copy()
l1[-1].append(666)
print(l1,l2)       #第二层开始与原数据公用:[1, 2, 3, [22, 666]] [1, 2, 3, [22, 666]]

print(id(l1))   #2357463048008
print(id(l2))  # 2357463013768
print(id(l1[-1]))  # 2357463047816
print(id(l2[-1]))  # 2357463047816

深copy
import copy
l1 = [1,2,3,[22,]]
l2 = copy.deepcopy(l1)
print(l1,l2)   # [1, 2, 3, [22]]    [1, 2, 3, [22]]
l1[-1].append(666)  
print(l1)   # [1, 2, 3, [22, 666]]

print(l2)   # [1, 2, 3, [22]]

切片属于浅copy
l1 = [1,2,3,[22,33]]
l2 = l1[:]
# l1.append(666)
l1[-1].append(666)
print(l2)  # [1, 2, 3, [22, 33, 666]]

原文地址:https://www.cnblogs.com/yidashi110/p/10092290.html

时间: 2024-11-09 07:22:37

python之数据类型补充、集合、深浅copy的相关文章

python基础(9):基本数据类型四(set集合)、基础数据类型补充、深浅拷贝

1. 基础数据类型补充 li = ["李嘉诚", "麻花藤", "?海峰", "刘嘉玲"] s = "_".join(li) print(s) li = "?花?闺?" s = "_".join(li) print(s) 列表: 循环删除列表中的每?个元素 li = [11, 22, 33, 44] for e in li: li.remove(e) print(li

python之旅 1-29 补充内容,深浅copy

#  l1 = [111,222,333,444,555] 将索引为奇数位的元素删除. # l1 = [111,222,333,444,555] # del l1[1::2] # print(l1) 通过删除列表中的元素 # for i in range(len(l1)-1,0,-1): # if i%2==0: # del l1[i-1] # print(l1) 通过循环列表,用range指代索引位置 for i in l1: if l1.index(i)%2==0: l2.append(i)

python集合深浅copy

01昨天内容回顾 代码块:由一个文件,一个函数,一个模块,一个类,交互模式下每一行都是一个代码块 Is == id:id()是查询内存地址,==比较两边的值,is是比较两边的内存地址. 小数据池: 在内存中创建一个池,提前存放了-5~256的整数,一定规则的字符串,后续程序中,如果设置的变量指向的是小数据内容,那就不会再内存中重新创建. 1.节省内存 2.提高性能和效率. 小数据池和代码块的关系. 同一个代码块:python在执行时,遇到了初始化对象,他会将这个变量和数值放在一个字典中,再次遇到

Python 集合 深浅copy

一,集合. 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系测试,测试两组数据之前的交集.差集.并集等关系. 1,集合的创建. set1 = set({1,2,'barry'}) set2 = {1,2,'barry'} print(set1,set2) # {1, 2, 'barry'} {1, 2, 'barry'} 2,集合的增. set1 =

python--基础数据类型的补充与深浅copy

一 . join的用法 lst =['吴彦祖','谢霆锋','刘德华'] s = '_'.join(lst) print(s) # 吴彦祖_谢霆锋_刘德华 # join() "*".join("吴彦祖") # 吴*彦*祖 把传递进去的参数进行迭代. 获取到的每个元素和前面的*进行拼接. 得到的是字符串 split() 切割. 切割的结果是列表 二 . 对正在循环的列表或者字典的删除方法 列表和字典: 都不能在循环的时候直接删除 把要删除的内容记录在新列表中然后循环这

python 06 id is == set 深浅copy

01 今日内容大纲 is==id用法 代码块 同一代码下的缓存机制 不同代码下的缓存机制(小数据池) 总结 集合(了解,但金融有时候会用到) 深浅copy 02 昨日回顾 is id == 字典初识: 查询速度快,存储大量的关联性数据 键:是不可变数据类型,比如str bool int tuple,并且是唯一的 值:可以是任意数据类型,对象 字典3.5x之前是无序的,3.6x按照初始时的顺序排列,3.7之后是有序的 增删改查: 增:setdefault(),dic['age']=18 删:pop

python基础数据类型补充以及编码的进阶

一. 基础数据类型补充内容 1.1 字符串 字符串咱们之前已经讲了一些非常重要的方法,剩下还有一些方法虽然不是那么重要,但是也算是比较常用,在此给大家在补充一些,需要大家尽量记住. #captalize :首字母大写 #swapcase :大小写翻转 #title :每个单词的首字母大写 #center :内同居中,总长度,空白处填充 #寻找字符串中的元素是否存在 #find :返回的找到的元素的索引,如果找不到返回-1 #index :返回的找到的元素的索引,找不到报错. #captalize

set集合,深浅copy

一基础数据类型补充: 1.jion,把列表转换成字符串 s=['多闻天王,增长天王,持国天王,广法天王'] s2=s.join('*') print(s2) #多闻天王*增长天王*持国天王*广法天王 2.列表list里的元素不能直接删除.适用于字典dict 原因:for的运行过程,会有一个指针来记录当前循环的元素是哪一个,一开始这个指针指向第0个,然后获取到第0个元素,紧接着删除第0个.这个时候,原来的第一个元素会自动的变成第0个,然后指针向后移动一次,指向1元素.这时原来的1已经变成了0,也就

python基础数据类型补充以及编码进阶

01 内容大纲 基础数据类型的补充 数据类型之间的转换 编码的进阶 02 具体内容: 数据类型的补充: str # str :补充的方法练习一遍就行. s1 = 'taiBAi' # capitalize 首字母大写,其余变小写 print(s1.capitalize()) # swapcase 大小写翻转 print(s1.swapcase()) # title 每个单词的首字母大写 msg= 'taibai say3hi' print(msg.title()) s1 = 'barry' #