Python基本数据类型( 字典 集合 )

字典 dict

   字典是python中唯一的映射类型,采用键值对(key-value)的形式存储数据。python对key进行哈希函数运算,根据计算的结果决定value的存储地址,所以字典是无序存储的,且key必须是可哈希的。可哈希表示key必须是不可变类型,如:数字、字符串、元组。

  字典(dictionary)是除列表意外python之中最灵活的内置数据结构类型。列表是有序的对象结合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式为 dict = {key1 : value1, key2 : value2 }

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

#直接新增键值对
>>> dict = {'aaa': '2341', 'bbb': '9102', 'ccc': '3258'} >>> print(dict) {'aaa': '2341', 'bbb': '9102', 'ccc': '3258'} >>> dict['li'] = ["a","b",3] >>> print(dict) {'aaa': '2341', 'bbb': '9102', 'ccc': '3258', 'li': ['a', 'b', 3]}
>>> dict['li'] = [] #这种方法在字典中添加键值对,如果只有键,对应的值是none,会更改数据
>>> print(dict)
{'aaa': '2341', 'bbb': '9102', 'ccc': '3258', 'li': []}

# setdefault >>> dict.setdefault('ttt','ggg') 'ggg' >>> print(dict) {'aaa': '2341', 'bbb': '9102', 'ccc': '3258', 'li': ['a', 'b', 3], 'ttt': 'ggg'} >>> dict.setdefault(123,345) 345 >>> print(dict) {'aaa': '2341', 'bbb': '9102', 'ccc': '3258', 'li': ['a', 'b', 3], 'ttt': 'ggg', 123: 345} >>> dict.setdefault(888) # setdefault 在字典中添加键值对,如果只有键,那对应的值是none >>> print(dict) {'aaa': '2341', 'bbb': '9102', 'ccc': '3258', 'li': ['a', 'b', 3], 'ttt': 'ggg', 123: 345, 888: None} >>> dict.setdefault(123) # 但是如果原字典中存在设置的键值对,则他不会更改或者覆盖 345 >>> print(dict) {'aaa': '2341', 'bbb': '9102', 'ccc': '3258', 'li': ['a', 'b', 3], 'ttt': 'ggg', 123: 345, 888: None}

#    pop 
>>> print(dict)
{'bbb': '9102', 'ccc': '3258', 'li': [], 123: 345, 888: None}
>>> dic_pop=dict.pop(123)              # pop根据key删除键值对,并返回对应的值,如果没有key则返回默认返回值
>>> print(dic_pop)
345
>>> print(dict)
{'bbb': '9102', 'ccc': '3258', 'li': [], 888: None}
>>> dic_pop=dict.pop('ccc','3258')
>>> print(dic_pop)
3258
>>> print(dict)
{'bbb': '9102', 'li': [], 888: None}
>>> dic_pop=dict.pop(888)
>>> print(dic_pop)
None
>>> print(dict)
{'bbb': '9102', 'li': []}

#    popitem    随机返回并删除字典中的一对键和值(一般删除末尾对)
>>> print(dict)
{'bbb': '9102', 'li': ['a', 'b', 3], 123: None, 888: 'jjk', 'l': [3333]}
>>> dic_popitem=dict.popitem()     # 随机删除字典中的某个键值对,将删除的键值对以元祖的形式返回    
>>> print(dic_popitem)
('l', [3333])
>>> dic_popitem=dict.popitem()
>>> print(dic_popitem)
(888, 'jjk')
>>> dic_popitem=dict.popitem()
>>> print(dic_popitem)
(123, None)
>>> dic_popitem=dict.popitem()
>>> print(dic_popitem)
('li', ['a', 'b', 3])

#   del   删除,没有返回值
>>> print(dict)
{'bbb': '9102', 888: 'jjk', 'fff': 555, 'abc': 'xyz'}
>>> del dict[888]   #删除键值对
>>> print(dict)
{'bbb': '9102', 'fff': 555, 'abc': 'xyz'}
# del dict #删除字典
# clear 清空 >>> dict.clear() >>> print(dict) {} # none >>> print(dict) {'abc': 'xyz', 'a': 'gg'} >>> ffff=dict.clear() >>> print(ffff) None

>>> dic = {"name":"jin","age":18,"sex":"male"}
>>> dic2 = {"name":"alex","weight":75}
>>> dic2.update(dic)     # 将dic所有的键值对覆盖添加到dic2中 (相同key的覆盖,没有的添加)
>>> print(dic2)
{'name': 'jin', 'weight': 75, 'age': 18, 'sex': 'male'}

>>> print(dic)
{'name': 'jin', 'age': 18, 'sex': 'male'}
>>> dic['name']
'jin'
>>> print(dic['name'])
jin
>>> print(dic['hhh'])             #没有会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'hhh'

>>> dic.get('age')
18
>>> dic.get('a')               #没有不报错
>>> gggg=dic.get('a')      #返回设定的返回值
>>> print(gggg)
None
    

其他操作

>>> dic = {"name":"jin","age":18,"sex":"male"}

>>> item=dic.items()
>>> print(item,type(item))
>>> print(item,'===>',type(item))
dict_items([('name', 'jin'), ('age', 18), ('sex', 'male')]) ===> <class 'dict_items'>     # 这个类型就是dict_items类型,可迭代的

>>> keys = dic.keys()
>>> print(keys,'===>',type(keys))
dict_keys(['name', 'age', 'sex']) ===> <class 'dict_keys'>

>>> print(values,'===>',type(values))
dict_values(['jin', 18, 'male']) ===> <class 'dict_values'>    #同上

#字典的循环
>>> dic = {"name":"jin","age":18,"sex":"male"}
>>> for key2 in dic:
...     print(key2)
... 
name
age
sex
>>> for item2 in dic.items():
...     print(item2)
... 
('name', 'jin')
('age', 18)
('sex', 'male')
>>> for key2,value2 in dic.items():
...     print(key2,value2)
... 
name jin
age 18
sex male

集合

集合(set)是一个无序的不重复元素序列。它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的。以下是集合最重要的两点:

  去重,把一个列表变成集合,就自动去重了。

  关系测试,测试两组数据之前的交集、差集、并集等关系。

创建集合

可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典

创建格式: parame = {value01,value02,...}  或者  set(value)

>>> set('jkhh')
{'j', 'k', 'h'}

>>>basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # 这里演示的是去重功能
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # 快速判断元素是否在集合内
True
>>> 'crabgrass' in basket
False
 
>>> # 下面展示两个集合间的运算.
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # 集合a中所有b没有的元素
{'r', 'd', 'b'}
>>> a | b                              # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b                              # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print (basket)
{'apple', 'orange', 'banana', 'pear'}
>>> basket.add(123)             #
>>> print (basket)
{'apple', 'banana', 'pear', 'orange', 123}

#  迭代着增加
>>> basket.update('A')
>>> print (basket)
{'apple', 'banana', 'pear', 'A', 'orange', 123}
>>> basket.update('奈斯')
>>> print (basket)
{'apple', 'banana', 'pear', '', 'A', 'orange', '', 123}
>>> basket.update('奈斯')
>>> print (basket)
{'apple', 'banana', 'pear', '', 'A', 'orange', '', 123}
>>> basket.update([1,2,3,'kkk'])
>>> print (basket)
{'apple', 'banana', 'pear', 1, 2, 3, '', 'A', 'kkk', 'orange', '', 123}

>>> print (basket)
{'apple', 'banana', 'pear', 1, 2, 3, '3', '1', '2', '', 'A', 'kkk', 'orange', '', 123}
>>> basket.remove('2')         #删除一个元素
>>> print (basket)
{'apple', 'banana', 'pear', 1, 2, 3, '3', '1', '', 'A', 'kkk', 'orange', '', 123}

>>> basket.pop()               #随机删除一个元素
'apple'
>>> print (basket)
{'banana', 'pear', 1, 2, 3, '3', '1', '', 'A', 'kkk', 'orange', '', 123}

>>> basket.discard(3) #移除集合中的元素,且如果元素不存在,不会发生错误
>>> print (basket)
{'banana', 1, 2, 'pear', '3', '1', '奈', 'A', 'kkk', 'orange', '斯', 123}
>>> basket.clear() #清空集合 >>> print (basket) set() >>> del basket #删除集合 >>> print (basket) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'basket' is not defined

其他操作

#    交集。(&  或者 intersection)
>>> set1={1,2,3,4,5}
>>> set2={3,4,5,6,6,7,8}
>>> print(set1 & set2)
{3, 4, 5}
>>> print(set1.intersection(set2))
{3, 4, 5}

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

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

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


#    子集与超集
set1 = {1,2,3}
set2 = {1,2,3,4,5,6}

print(set1 < set2)          #返回 True  反过来返回 False
print(set1.issubset(set2))  # 这两个相同,都是说明set1是set2子集。

print(set2 > set1)
print(set2.issuperset(set1))  # 这两个相同,都是说明set2是set1超集。

基础数据类型小结

#按存储空间的占用分(从低到高)
数字
字符串
集合:无序,即无序存索引相关信息
元组:有序,需要存索引相关信息,不可变
列表:有序,需要存索引相关信息,可变,需要处理数据的增删改
字典:无序,需要存key与value映射的相关信息,可变,需要处理数据的增删改

#按存值个数区分
标量/原子类型:    数字,字符串
容器类型:            列表,元组,字典

#按可变不可变区分
可变:            列表,字典
不可变:        数字,字符串,元组,布尔值

#按访问顺序区分
直接访问                    数字
顺序访问(序列类型)    字符串,列表,元组
key值访问(映射类型)    字典        

 深浅拷贝

1. 先看赋值运算

l1 = [1,2,3,['barry','alex']]
l2 = l1

l1[0] = 111
print(l1)  # [111, 2, 3, ['barry', 'alex']]
print(l2)  # [111, 2, 3, ['barry', 'alex']]

l1[3][0] = 'wusir'
print(l1)  # [111, 2, 3, ['wusir', 'alex']]
print(l2)  # [111, 2, 3, ['wusir', 'alex']]

对于赋值运算来说,L1与L2指向的是同一个内存地址,所以他们是完全一样的

2. 浅拷贝  copy

>>> w1 = [1,2,3,['barry','alex']]
>>> w2 = w1.copy()
>>> print(w1,id(w1))
[1, 2, 3, ['barry', 'alex']] 139935607860680
>>> print(w2,id(w2))
[1, 2, 3, ['barry', 'alex']] 139935613174088


>>> w1[1] = 22
>>> print(w1,id(w1))
[1, 22, 3, ['barry', 'alex']] 139935607860680
>>> print(w2,id(w2))
[1, 2, 3, ['barry', 'alex']] 139935613174088        ##### 第一层不跟着变


>>> w1[3][1] = 'gg'
>>> print(w1,id(w1))
[1, 22, 3, ['barry', 'gg']] 139935607860680
>>> print(w2,id(w2))
[1, 2, 3, ['barry', 'gg']] 139935613174088         ##### 从第二层开始跟着变 

>>> w2[3][0] = 'py' >>> print(w1,id(w1)) [1, 22, 3, ['py', 'gg']] 139935607860680 ##### 改任意一个, 另一个也跟着变 >>> print(w2,id(w2)) [1, 2, 3, ['py', 'gg']] 139935613174088

对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性.

3. 深拷贝  deepcopy

>>> import copy                     #必须有
>>> y1 = [1,2,3,['barry','alex']]
>>> y2 = copy.deepcopy(y1)
>>> print(y1,id(y1))
[1, 2, 3, ['barry', 'alex']] 139935607860232
>>> print(y2,id(y2))
[1, 2, 3, ['barry', 'alex']] 139935610400904


>>> y1[1] = 222
>>> print(y1,id(y1))
[1, 222, 3, ['barry', 'alex']] 139935607860232
>>> print(y2,id(y2))
[1, 2, 3, ['barry', 'alex']] 139935610400904     #没变


>>> y1[3][0] = 'py'
>>> print(y1,id(y1))
[1, 222, 3, ['py', 'alex']] 139935607860232
>>> print(y2,id(y2))
[1, 2, 3, ['barry', 'alex']] 139935610400904     #也没变

对于深copy来说,两个是完全独立的,改变任意一个的任何元素(无论多少层),另一个绝对不改变。

 

posted @ 2018-10-24 18:09  mingetty  阅读(263)  评论(0)    收藏  举报