list\tuple\str\bytes\bytearray\set\dict
字典 dict
key-value 键值对的数据集合
可变的、无序的、key不重复的
字典dict定义、初始化
d = dict()或者d={}
dict(**kwargs)使用name=value对初始化一个字典,d=dict(a=5,b=6,c=[1,2,3])
数字是可以作为key。
dict(iterable,**kwarg)使用可迭代对象和name=value对构造字典,不过可迭代对象的元素必须是一个二元结构。
d = dict((1,'a'),(2,'b')) 或者 d = dict(([1,'a'],[2,'b']))
dict(mapping,**kwarg)使用一个字典构造另一个字典
d = {'a':10,'b':20,'c':None,'d':[1,2,3]}
类方法dict.fromkeys(iterable,value)
d = dict.fromkeys(range(5))
d = dict.fromkeys(range(5),0)
在用引用类型,做构造的时候,一定要特别小心。
类方法,相当于java当中的静态方法
字典元素的访问
d[key]
返回key对应的值value
key不存在抛出KeyError异常
get(key[,default])
返回key对应的值value
key不存在返回缺省值,如果没有设置缺省值,就返回None。
这个方法,比较安全,有就返回,没有就返回None,能够用来判断。
setdefault(key[,default])
返回key对应的值value
key不存在,添加kv对,value为default,并返回default,如果default没有设置,缺省为None
get方法和setdefault方法,两个是使用最多的。
f = d2.setdefault(4,400)
f = d2.setdefault(4,401)
setdefault,缺省值,没有就给缺省值,有了就不给了。
连set带get,这个也比较常用。
有时候key不存在出问题,又不想破坏原来值,又拍不存在。
d[key]和get(key[,default])也算是比较常用。
字典的增加和修改
d[key]=value
将key对应的值修改为value
key不存在添加新的kv对
update([other]) -> None
使用另一个字典的kv对更新本字典。
key不存在,就添加
key存在,覆盖已经存在的key对应的值
就地修改
d.update(red=1)
d.update((('red',2),))
d.update({'red':3})
d[100] = 100
d[100] = 1000 # 有就覆盖,没有就创建
字典当中,显示的时候,就是无序的。
元素的修改,就是用key,看似是名称索引。
样子有点像是关联数组那种样子。
update([other])这是要就地修改。
使用另一个字典的kv对更新本字典。
本字典如果有这个key,就带来问题的。
key存在覆盖,不存在就添加。
d3 = {100:2000,5:'abc'}
d2.update(d3,red=1) # 关键字参数,往最后面放,单值往前放
d.update({'red':3}) # 这括号里面是字典
d.update((('red',2),)) # 二元组
字典的构造函数,是很灵活的。
字典元素是kv对的,用法,很不一样
字典删除
pop(key[,default])
key存在,移除它,并返回它的value
key不存在,返回给定的default
default未设置,key不存在则抛出KeyError异常
popitem()
移除并返回一个任意的键值对
字典为empty,抛出KeyError异常
clear()
清空字典
散记:
一个键值对,凑起来,就是item。
d1.pop() # 不行
d1.pop(10)
f = d1.pop(8) # pop出来的,如果是引用类型的,就是一个地址
f.append(4) # 全部都改了
d1
d1.popitem() # 没有参数,一个kv对是返回值,是个二元组。
pop用的很少,popitem用的还是比较多。
kv对,字典做好了,是很少移除的。
而且一边迭代for,一边remove,pop,是不可以的。
字典删除
del语句
a = True
b =[6]
d={'a':1,'b':'b','c':[1,3,4]}
del a # 删除掉,这个对象就没有了。
del d['c'] # 删除了一个对象[1,3,5]?
del b[0]
c=b
del c
del b
b = d['b']
del看起来是删除了一个对象,实际上删除的,是一个引用计数。
本质上减少了一个对象的引用,del实际上删除的是名称,而不是对象
字典遍历(重要)
for ... in dict
遍历key
for k in d:
print(k)
for k in d.keys():
print(k)
遍历value
for k in d:
print(d[k])
for k in d.keys():
print(d.get(k))
item遍历,d.items()
for item in d2.values():
print(item) # 打印value
for v in d2.keys():
print(d2[v])
for item in d.items():
print(item) # 二元组
for k,v in d.items(): # 这里还能够用解构
print(k,v)
for k,_ in d.items():
print(k)
总结:
python3当中,keys、values、items方法,返回一个类似一个生成器的可迭代对象,
实际上是在原集合类型上,进行迭代的。
不会把函数的返回结果赋值到内存中
python2当中,上面的方法会返回一个新的列表,占据新的内存空间。
所以python2建议使用iterkeys,itervalues,iteritems版本,
返回一个迭代器,而不是一个copy
字典
字典是非常常用的数据结构。在任何一个编程语言当中,都很重要。
字典的特性,就是它的key。
for in 里面的解构,情况很多。
字典的key
key的要求和set的元素要求一致
hashable 可哈希,才可以作为key
d = {1:0,2.0:3,'abc':None,('hello','world','python'):'string',b'abc':'135'}
('hello','world','python')和b'abc',不行。
defaultdict - 缺省字典
collection.defaultdict([default_factory[,...]])
第一个参数是default_factory,缺省是None,它提供一个初始化函数。
当key不存在的时候,会调用这个工厂函数来生成key对应的value。
from collections import defaultdict
d1 = {}
d2 = defaultdict(list) # list() list是callable对象 list这里表示个函数名
for k in 'abcde':
for v in range(5):
if k not in d1.keys():
d1[k]=[]
d1[k].append(v)
print(d1)
for k in 'mnopq':
for v in range(3):
d2[k].append(v)
print(d2)
OrderedDict
collections.OrderedDict([items])
key并不是按照加入的顺序排列,可以使用OrderedDict记录顺序
from collections import OrderedDict
import random
d = {'banana':3,'apple':4,'pear':1,'orange':2}
print(d)
keys=list(d.keys())
random.shuffle(keys)
print(keys)
od=OrderedDict()
for key in keys:
od[key]=d[key]
print(od)
print(od.keys())
有序字典,可以记录元素插入的顺序,打印的时候,也是按照这个顺序输出打印的。
3.6版本的python的字典,就是记录key插入的顺序的。
字典练习
第一题
用户输入一个数字
打印每一位数字及其重复的次数
第二题
数字重复统计
随机产生100个整数
数字的范围[-1000,1000]
升序输出所有不同的数字及其重复的次数
第三题
字符串重复统计
字符表'abcdefghijklmnopqrstuvwxyz'
随机挑选2个字母组成字符串,一共挑选100个
降序输出这100个字符串及重复的次数