python 字典Dict
字典Dict
-
key-value键值对的数据的集合
-
可变的、无序的、key不重复
字典dict定义、初始化
-
d = dict() 或者d = {}
-
dict(**kwargs) 使用name=value对初始化一个字典
-
dict(iterable, **kwarg) 使用可迭代对象和name=value对构造字典,不过可迭代对象的元素必须是
一个二元结构(可迭代对象的元素必须是
一个二元结构!二元结构!二元结构!)- d = dict(((1,‘a’),(2,‘b’))) 或者d = dict(([1,‘a’],[2,‘b’]))
-
dict(mapping, **kwarg) 使用一个字典构建另一个字典
-
类方法dict.fromkeys(iterable, value)
- d = dict.fromkeys(range(5))
{0: None, 1: None, 2: None, 3: None, 4: None}
- d = dict.fromkeys(range(5),0)
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
字典元素的访问
d[key]
-
返回key对应的值value
-
key不存在抛出KeyError异常
dict1 = {1:100}
dict1[0] #如果value不存在,返回keyError
get(key[, default])
-
返回key对应的值value
-
key不存在返回缺省值,如果没有设置缺省值就返回None
dict1 = {1:100}
dict1.get(10) #如果value不存在,返回None
dict1.get(10,100) #如果k不存在,临时创建一个值
setdefault(key[, default])
-
返回key对应的值value
-
key不存在,添加kv对,value为default,并返回default,如果default没有设置,缺省为None
dict1 = {1:100}
dict1.setdefault(10,3000) #返回对应的value,如果不存在新建键值对
字典增加和修改
d[key] = value
-
将key对应的值修改为value
-
key不存在添加新的kv对
update([other]) -> None
-
使用另一个字典的kv对更新本字典
-
key不存在,就添加
-
key存在,覆盖已经存在的key对应的值
-
就地修改
update((('red',2),)) update({'red':3}) dict.update(a=100) dict1.update(((3,300),),a='abc') #这里等式要靠后写,否则可能出现错误
- dict1,update(3=500) 这样的方法不可行,3是字面常量
字典删除
pop(key[, default])
-
key存在,移除它,并返回它的value
-
key不存在,返回给定的default
-
default未设置,key不存在则抛出KeyError异常
popitem()
-
移除并返回一个任意的键值对
-
字典为empty,抛出KeyError异常
dict1 = {1:100,'a':200,2:300}
dict1.popitem()
clear()
- 清空字典 (清除字典的地址引用计数)
del语句
a = True
b = [6]
d = {'a': 1, 'b': b, 'c': [1,3,5]}
del a
del d['c'] # 字典中[1,3,5]引用计数减1
del b[0] -->[]
c = b
del c
del b
b = d['b']
- del a[‘c’] 看着像删除了一个对象,本质上减少了一个对象的引用,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)) for v in d.values(): print(v)
- 遍历item,即kv对
for item in d.items(): print(item) for item in d.items(): print(item[0], item[1]) for k,v in d.items(): print(k, v) for k, _ in d.items(): print(k) for _ ,v in d.items(): print(v)
总结
- Python3中,keys、values、items方法返回一个类似一个生成器的可迭代对象,不会把函数的返回结果复制到内存中
-
Dictionary view对象,可以使用len()、iter()、in操作
-
字典的entry(item)的动态的视图,字典变化,视图将反映出这些变化
-
keys返回一个set对象,也就是可以看做一个set集合
-
如果values都可以hash,那么items也可以看做是类set对象
-
- Python2中,上面的方法会返回一个新的列表,占据新的内存空间。所以Python2建议使用iterkeys、itervalues、iteritems版本,返回一个迭代器,而不是一个copy
字典遍历和移除
如何在遍历的时候移除元素
-
错误做法
d = dict(a=1, b=2, c='abc') for k,v in d.items(): d.pop(k) # 异常 RuntimeError: dictionary changed size during iteration
[注]: items方法返回Dictionary view对象,其本质还是在操作原有dict,在迭代过程中不允许改变字典的size
while len(d): # 相当于清空,不如直接clear() print(d.popitem())
-
正确做法
d = dict(a=1, b=2, c='abc') keys = [] for k,v in d.items(): if isinstance(v, str): keys.append(k) for k in keys: d.pop(k) print(d)
字典的key
key的要求和set的元素要求一致
-
set的元素可以就是看做key,set可以看做dict的简化版
-
hashable 可哈希才可以作为key,可以使用hash()测试
defaultdict
collections.defaultdict([default_factory[,…]])
-
第一个参数是default——factory,缺省是None,它提供一个初始化函数。当key不存在的时候会调用这个工厂函数来生产key对应的value
import random d1 = {} for k in 'abcdef': for i in range(random.randint(1,5)): if k not in d1.keys(): d1[k] = [] d1[k].append(i) print(d1)
from collections import defaultdict import random d1 = defaultdict(list) for k in 'abcdef': for i in range(random.randint(1,5)): d[k].append[i] print(d1)
OrderedDict
collections.OderedDict([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插入的顺序
-
应用场景:
- 假如使用字典记录了N个产品,这些产品使用ID由小到大加入到字典中
- 除了使用字典检索的遍历,有时候需要取出ID,但是希望是按照输入的顺序,因为输入顺序是有序的
- 否则还需要重新把遍历到的值排序
字典练习
用户输入一个数字
-
打印每一位数字及其重复的次数
numcount = {} for _ in range(5): num = input('input a number:').strip().lstrip('0') if num not in numcount.keys(): numcount[num] = 1 else: numcount[num] += 1 for k,v in numcount.items(): print(k,v)
numcount = {} for _ in range(5): num = input('input a number:').strip().lstrip('0') numcount.setdefault(num,0) if num in numcount.keys(): numcount[num] += 1 for item in numcount.items(): print(item)
数字重复统计
- 随机产生100个整数
- 数字的范围[-1000, 1000]
- 升序输出所有不同的数字及其重复的次数
import random
dict1 = {}
n = 100
lst = [random.randint(-1000,1000) for _ in range(n)]
for i in range(n):
flag = False
for j in range(n-i-1):
if lst[j] > lst[j+1]:
lst[j],lst[j+1] = lst[j+1],lst[j]
flag = True
if not flag:
break
for k in lst:
if k not in dict1.keys():
dict1[k] = 1
else:
dict1[k] += 1
print(dict1)
字符串重复统计
-
字符表’abcdefghijklmnopqrstuvwxyz’
-
随机挑选2个字母组成字符串,共挑选100个
-
降序输出所有不同的字符串及重复的次数
import random
str = 'abcdefghijklmnopqrstuvwxyz'
strdict = {}
strgrouplist = []
n = 100
for _ in range(n):
strgroup = ''.join(random.sample(str,2))
strgrouplist.append(strgroup)
for i in range(n):
flag = False
for j in range(n-i-1):
if strgrouplist[j] < strgrouplist[j+1]:
strgrouplist[j],strgrouplist[j+1] = strgrouplist[j+1],strgrouplist[j]
flag = True
if not flag:
break
for k in strgrouplist:
if k in strdict:
strdict[k] += 1
else:
strdict[k] = 1
print(strdict)