流程python学习笔记:第三章(2)

第三章之字典的变种:
OrderedDict
首先来看下面的代码,在一个字典中,有name,age,city,在遍历这个字典的时候。顺序却是随机的,不是按照我们添加的顺序也就是name->age->city
d={}

d['name']='zhf'

d['age']=33

d['city']='chengdu'

for k,v in d.items():

    print k,v
city chengdu
age 33
name zhf
我们如果想字典按照我们添加的顺序呈现出来,就必须用到OrderedDict.
from collections import OrderedDict
d1=OrderedDict()

d1['name']='zhf'

d1['age']=33

d1['city']='chengdu'

for k,v in d1.items():

    print k,v
结果如下,遍历的时候就和添加的顺序一致了。
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py
name zhf
age 33
city Chengdu
 
collections.Counter:
这个映射类型是给对象准备一个整数计数器。比如有字符:aaaabccc.那么Counter将会去计算每个字符出现的次数,并返回一个字典。
ct=Counter('aaaabccc')

print ct
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py
Counter({'a': 4, 'c': 3, 'b': 1})
 
可以看到返回的是一个字典,因此我们可以用字典的方式去获取到它对应的计数值。ct['a']。当去获取一个不存在的字母的时候,则会返回0.例如 ct['d']的返回结果就是0
当更新这个字符的时候,计数器会在上一次的基础上进行更新。
ct=Counter('aaaabccc')

ct.update('adef')

print ct

for c in ct.elements():

    print c
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py
Counter({'a': 5, 'c': 3, 'b': 1, 'e': 1, 'd': 1, 'f': 1})
a
a
a
a
a
c
c
c
b
e
d
f
可以看到初始字符为aaaabccc, 更新添加adef后,a的次数变为5.整个字符串就变成aaaaacccbedf
 
集合:
集合的本质是许多唯一对象的聚集。因此集合可以去掉重复的元素。参考下面的代码
d=['abc','def','abc','def']

s=set(d)

print s
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py
set(['abc', 'def'])
 
假设有2个集合ab,需要统计集合a的哪些元素在集合b中也出现。如果不使用集合,代码只能写成下面的形式:
a=['abc','def','aaa']

b=['abc','bbb','ccc','def']

for n in a:

    if n in b:

        print n
但是如果使用集合,则不用这么麻烦。在集合中。a|b返回的是合集,a&b返回的是交集。a-b返回的是差集。如下,用集合的话一行代码就搞定。
a=['abc','def','aaa']

b=['abc','bbb','ccc','def']

print set(a) & set(b)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py
set(['abc', 'def'])
 
合集的结果
print set(a) | set(b)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter3.py
set(['abc', 'aaa', 'ccc', 'bbb', 'def'])
 
差集的结果,差集是指属于A但不属于B的结合
print set(a)-set(b)
set(['aaa'])
 
对称差集:集合A与集合B中所有不属于AB的元素集合
print set(a)^set(b)
set(['ccc', 'aaa', 'bbb'])
 
 
关于字典,列表,集合运行效率的对比.
1 首先我们用haystack建立一个字典,里面的元素大小分别从1000增长到10000000.然后看下运行时间
start=time.clock()

for n in needles:

    if n in haystack:

        found+=1

end=time.clock()

print end-start





可以看出时间差别如此的大,对于列表而言,haystack的大小没增长10倍,运行时间呈线性增长。
为什么会导致如此大的区别呢,原因在于字典以及集合都用到了散列表,而列表没有用散列表,因此每次搜索列表都需要扫描一次完整的表。这里介绍下什么是散列表
散列表又叫hash表,是根据关键码的值而直接进行访问的数据结构。通过把关键码映射到表中的一个位置来访问表,以便加快访问速度。这个映射函数就叫散列函数。通俗点说就是对于存储在字典或者集合中的每一个组,都会计算一个hash值。这个hash值可以当做在字典和集合中存储的位置。然后查找的时候只需要计算这个hash值就可以找到存储的位置,这样就避免了遍历整个表。
 
字典的代码:
found=0

haystack={}

needles=[float(random.randint(0,500)) for i in range(500)]

length=10000000

for i,v in enumerate(range(length)):

    haystack[i]=(float(random.randint(0,length)))

start=time.clock()

for n in needles:

    if n in haystack:

        found+=1

end=time.clock()

print end-start
 
 
集合的代码:
found=0

haystack=set()

needles=[float(random.randint(0,500)) for i in range(500)]

length=1000

for i in range(length):

    haystack.add(float(random.randint(0,length)))

start=time.clock()

for n in needles:

    if n in haystack:

        found+=1

end=time.clock()

print end-start
 
列表的代码
found=0

haystack=[]

needles=[float(random.randint(0,500)) for i in range(500)]

length=10000

for i in range(length):

    haystack.append(float(random.randint(0,length)))

start=time.clock()

for n in needles:

    if n in haystack:

        found+=1

end=time.clock()

print end-start
 
 
既然字典和集合会保存一个hash表,那么肯定会比列表占据更多的内存。我们来实际看下是不是这样的。我们还是用profile来看下内存的增长
 
来看字典的
@profile

def memory_try():

    haystack={}

    length=10000000

    for i,v in enumerate(range(length)):

        haystack[i]=(float(random.randint(0,length)))







因此可以看出字典的高效率是用空间换时间得来的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿与代码

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值