python 常用语法及命令(三) 赋值和引用 深拷贝和浅拷贝 字典 集合set

python  赋值和引用

1、Python中一切皆为对象 

      不管是集合变量还是数值型或者字符串型的变量都是一个引用,都是指向对应内存空间中的对象。 一个对象都有两个标准的头部信息:一个类型标识符去标识这个对象的类型,以及一个引用的计数器,用来决定是不是可以回收这个对象。当没有对象指向这块内存区域,python会自动进行回收。

2、赋值操作总是储存对象的引用,而不是这些对象的拷贝。··

       python中的变量在赋值的时候创建,它可以引用所有类型的对象,变量就相当于一个指针,指向对象所占的内存空间

>>> a = 1
>>> b = a
>>> print("a的ID:",id(a))
a的ID: 1408529040
>>> print("b的ID:",id(b))
b的ID: 1408529040
>>> a = 3
>>> print('a=%d  ,b=%d  ' % (a,b))
a=3  ,b=1  
>>> print("a的ID:",id(a))
a的ID: 1408529104
>>> print("b的ID:",id(b))
b的ID: 1408529040

这里a赋值给b之后,a和b的地址是相同的,他们指向同一个对象的内存空间,当改变对a赋值常量,这时候开辟了新的内存空间存放3,这是a指向了新的内存空间,a和b的地址不在相同

>>> list1 = [1,2,3]
>>> list2 = list1
>>> print("list1的ID:",id(list1))
list1的ID: 1230502136904
>>> print("list2的ID:",id(list2))
list2的ID: 1230502136904
>>> list1[0] = 0
>>> print('list1=%s  ,list2=%s  ' % (list1,list2))
list1=[0, 2, 3]  ,list2=[0, 2, 3] 

 上面list1和list2指向同一内存空间,改变其中一个列表中的元素,另一个也会改变

深拷贝和浅拷贝 

深拷贝和浅拷贝的区别在python里,主要是list列表中的元素如果还是个列表,这就需要使用深拷贝,因为只是浅拷贝的话,列表中的列表在list1和list2中是同一块内存。

>>> list1 = [1,2,3]
>>> list1 = [1,2,3,[4,5,6],7]
>>> list2 = list1[:]
>>> print("list1的ID:",id(list1))
list1的ID: 1230502136712
>>> print("list2的ID:",id(list2))
list2的ID: 1230502136776
>>> print("list1[3]的ID:",id(list1[3]))
list1[3]的ID: 1230502135944
>>> print("list2[3]的ID:",id(list2[3]))
list2[3]的ID: 1230502135944

 列表中的切片是浅拷贝,这里会看到list1和list2指向不同内存空间,但是他们的第三个元素也就是列表中的列表,是同一个内存空间的数据,也就是说浅拷贝不能拷贝列表中的列表。当然元祖也是相同的,但是元组是不能修改的,安全一些。

 所以这里要使用深拷贝  import copy 中的copy.deepcopy()

>>> list1 = [1,2,3,[4,5,6],7]
>>> list2 = list1[:] #浅拷贝
>>> list3 = copy.deepcopy(list1) #深拷贝
>>> print("list1[3]的ID:",id(list1[3]))
list1[3]的ID: 1230502136904
>>> print("list2[3]的ID:",id(list2[3]))
list2[3]的ID: 1230502136904             #浅拷贝的列表中的列表地址和list1相同
>>> print("list3[3]的ID:",id(list3[3]))
list3[3]的ID: 1230502136456             #深拷贝的列表中的列表地址和list1就不相同了

更详细的的深拷贝和浅拷贝的内容(https://www.cnblogs.com/zipxzf/articles/9737680.html)

这里注意:列表和数组不同,numpy ndaray数组中切片和np.view()相同,创建一个数组的视图,不是拷贝。

python 字典

1、{key:value}   健:值

一个对象能不能作为字典的key,就取决于其有没有__hash__方法。所以所有python自带类型中,除了list、dict、set和内部至少带有上述三种类型之一的tuple之外,其余的对象都能当key。

字典是映射类型,列表元祖字符串是序列类型

dict1 = {} 创建字典

dict() 函数创建字典

>>> dict1 = dict((('a',1),('b',2),('c',3),('d',4)))
>>> dict1
{'c': 3, 'b': 2, 'd': 4, 'a': 1}

 字典是无序的,所以dict[1]会报错

键值不存在,赋值会创建键值对

>>> dict1['e']  = 5
>>> dict1
{'c': 3, 'b': 2, 'd': 4, 'a': 1, 'e': 5}

2、内建函数

1> fromkeys() 返回字典

>>> dict1={}
>>> dict1.fromkeys((1,2,3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1,2,3),'Number')
{1: 'Number', 2: 'Number', 3: 'Number'}
>>> dict1.fromkeys((1,2,3),('one','two','three'))
{1: ('one', 'two', 'three'), 2: ('one', 'two', 'three'), 3: ('one', 'two', 'three')}
>>> dict1.fromkeys((1,3),'数字')
{1: '数字', 3: '数字'}

2> 访问字典 keys(),values(),items()  循环好搭档

  keys() 返回键

>>> for eachKey in dict1.keys():
...   print(eachKey)

values() 返回值

>>> for eachValue in dict1.values():
...   print(eachValue)

items() 返回键值对

>>> for eachItem in dict1.items():
...   print(eachItem)

3> get()

  字典访问键不存在会报错,使用get()访问不存在的健返回None,或者指定一个返回值

>>> dict1
{'c': 3, 'b': 2, 'd': 4, 'a': 1, 'e': 5}
>>> dict1.get('a')
1
>>> print(dict1['f'])   #报错
Traceback (most recent call last):
  File "<pyshell#96>", line 1, in <module>
    print(dict1['f'])
KeyError: 'f'
>>> print(dict1.get('f'))  #返回None
None
>>> dict1.get('f','不存在') #指定 get()返回值
'不存在'

 

4> in

in查找是否在字典中

>>> 'a' in dict1
True
>>> 'g' in dict1
False

5> clear()   清空字典

字典b赋值给字典a之后,clear()操作其中一个可以清空两个字典

>>> dict1.clear()
>>> dict1
{}

赋值是引用所以清空dict1,dict2也会被清空

>>> dict1 = {'a':1, 'b':2}
>>> dict1 = dict2
>>> dict1.clear()
>>> dict1
{}
>>> dict2
{}

 

6> copy()  浅拷贝

浅拷贝和赋值是不同的

>>> a.clear()
>>> a= {1:'one',2:'two',3:'three'}
>>> b=a.copy()
>>> c=a
>>> c
{1: 'one', 2: 'two', 3: 'three'}
>>> a
{1: 'one', 2: 'two', 3: 'three'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
>>> id(a)
1634644066520
>>> id(b)
1634644247824
>>> id(c)
1634644066520
>>> c[4]='four'
>>> c
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}

赋值的c和a地址相同,改变a,c也会改变而b不会被改变,

无条件值的分片以及字典copy方法只能做浅层复制,不能够复制嵌套的数据结构,如果需要一个深层嵌套的数据结构的完整的、完全独立的拷贝,那么就要使用标准的copy模块,即浅拷贝和深拷贝。

 

7> pop() 和 popitem 弹出 可以从字典里删除

pop(key)需要键值做参数,popitem()不要参数,弹出首个

>>> dict1
{'b': 2, 'd': 4, 'a': 1}
>>> dict1.pop('a')
1
>>> dict1.popitem()
('b', 2)

 

8> setdefault  

添加字典键值对,键不存在,值为None

>>> a.setdefault('呵')
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four', '呵': None}
>>> a.setdefault(5,'five')
'five'
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four', '呵': None, 5: 'five'}

构造值为列表的字典

>>> d={}
>>> d.setdefault('a',[]).append(1)
>>> d.setdefault('a',[]).append(2)
>>> d.setdefault('b',[]).append(4)
>>> d
{'a': [1, 2], 'b': [4]}

 也可以使用defaultdict

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['a'].append(1)
>>> d['a'].append(2)
>>> d['b'].append(4)
>>> d
defaultdict(<class 'list'>, {'a': [1, 2], 'b': [4]})

 default会自动为将要访问的键创建映射实体,setdefault不会

9> update()  更改值

>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four', '呵': None, 5: 'five'}
>>> b={'呵':'呵呵'}
>>> a.update(b)
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four', '呵': '呵呵', 5: 'five'}

 

python 集合 set 

1、set 也是用{}表示,没有映射关系

>>> num={}
>>> type(num)
<class 'dict'>
>>> num2={1,2,3,4,5}
>>> type(num2)
<class 'set'>

set中元素不能重复,set会删除重复的元素只保留一份,并且集合是无序的所以不支持索引

>>> num2={1,2,3,4,5,5,4,3,2}
>>> num2
{1, 2, 3, 4, 5}
>>> num2[2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing

2、set 创建

num = {1, 2, 3, 4, 5}

或用set()函数 参数可以使元组或者列表

>>> set1 =set([1,2,3,4,5,5])
>>> set1
{1, 2, 3, 4, 5}

3、in 和not in 判断元素是否在集合中

>>> num
{8, 9, 3, 5, 6}
>>> 8 in num
True
>>> 8 not in num
False
>>> 0 in num
False

4、add(num) 添加元素 和 remove(num) 删除元素

>>> num.add(10)
>>> num
{3, 5, 6, 8, 9, 10}
>>> num.remove(8)
>>> num
{3, 5, 6, 9, 10}

4、不可变集合 frozenset()

不能改变集合

>>> num = frozenset([1,2,3,4,5])
>>> num
frozenset({1, 2, 3, 4, 5})
>>> num.add(8)
Traceback (most recent call last):
  File "<pyshell#148>", line 1, in <module>
    num.add(8)
AttributeError: 'frozenset' object has no attribute 'add
集合类型内建方法总结


  

集合(s).方法名
等价符号
方法说明
s.issubset(t)s <= t子集测试(允许不严格意义上的子集):s 中所有的元素都是 t 的成员
 s < t子集测试(严格意义上):s != t 而且 s 中所有的元素都是 t 的成员
s.issuperset(t)s >= t超集测试(允许不严格意义上的超集):t 中所有的元素都是 s 的成员
 s > t超集测试(严格意义上):s != t 而且 t 中所有的元素都是 s 的成员
s.union(t)s | t合并操作:s "或" t 中的元素
s.intersection(t)s & t交集操作:s "与" t 中的元素
s.differences - t差分操作:在 s 中存在,在 t 中不存在的元素
s.symmetric_difference(t)s ^ t对称差分操作:s "或" t 中的元素,但不是 s 和 t 共有的元素
s.copy() 返回 s 的拷贝(浅复制)
以下方法仅适用于可变集合
  
s.updates |= t将 t 中的元素添加到 s 中
s.intersection_update(t)s &= t交集修改操作:s 中仅包括 s 和 t 中共有的成员
s.difference_update(t)s -= t差修改操作:s 中包括仅属于 s 但不属于 t 的成员
s.symmetric_difference_update(t)s ^= t对称差分修改操作:s 中包括仅属于 s 或仅属于 t 的成员
s.add(obj) 加操作:将 obj 添加到 s
s.remove(obj) 删除操作:将 obj 从 s 中删除,如果 s 中不存在 obj,将引发异常
s.discard(obj) 丢弃操作:将 obj 从 s 中删除,如果 s 中不存在 obj,也没事儿^_^
s.pop() 弹出操作:移除并返回 s 中的任意一个元素
s.clear() 清除操作:清除 s 中的所有元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值