# Python 高级应用--第二章

2-1 如何在列表,字典和集合中根据条件筛选数据

实际案例:

1.过滤列表[1,2,3,-6,-2,7,9,10]中的负数。

初级方法

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n6" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">data=[1,2,3,-2,2,-6,8]
res=[]
for x in data:
if x>=0:
res.append(x)
print(res)
</pre>

filter 函数

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n8" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
data=[randint(-10,10) for _ in range(10)]
print(data)
data1=list(filter(lambda x: x >= 0, data))
print(data1)</pre>

<mark style="box-sizing: border-box; background: rgb(255, 255, 0); color: rgb(0, 0, 0);">Notice</mark> 上面的代码中,randint 随机生成10个范围在-10到10之间的数。

filter 的第一个参数是用来筛选的函数,依次迭代传入的参数,然后被函数进行判断,返回布尔值,如果布尔值为真,则将这个值返回到最终的值,如果为假,就过滤掉。第二个参数是被筛选的数据在这里我们使用匿名函数来创建函数,筛选完之后的值要转换成列表才能进行输出。

列表解析:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n12" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
data=[randint(-10,10) for _ in range(10)] #创建列表为[]
data1=[x for x in data if x >= 0]
print(data1)</pre>

列表解析和filter 函数比较,使用timeit 函数来对两个方法的运行时间进行计算:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n14" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">timeit [x for x in data if x >= 0]
timeit filter(lambda x:x >= 0, data)</pre>

<mark style="box-sizing: border-box; background: rgb(255, 255, 0); color: rgb(0, 0, 0);">Notice</mark> 认为列表解析更快一点,我们首选的是列表解析。

2.对于字典中删除某些值对应的元素

示例:首先我们创建一个字典,键是20个同学的学号,值是每个同学的考试成绩。然后我们要根据值来筛选成绩在90分以上的同学。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n19" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
d={x: randint(60,100) for x in range(1,21)}
print(d)
dd={k:v for k,v in d.items if v > 90}
print(dd)</pre>

<mark style="box-sizing: border-box; background: rgb(255, 255, 0); color: rgb(0, 0, 0);">Notice</mark> 字典解析中的一个重要方法是items()iteritems

items :将字典中所有的项,以列表的方式返回。因为字典是无序的,所有items 返回的项也是无序的。

iteritems :与items 的方法相同,但是返回的不是列表,而是迭代器。iteritems 方法在需要迭代结果的时候使用最合适,而且它的工作效率非常高。

总结:在Python2.x中,iteritems() 用于返回本身字典列表操作后的迭代器【Returns an iterator on all items(key/value pairs) 】,不占用额外的内存。

在Python 3.x 里面,iteritems()方法已经废除了。在3.x里用 items()替换iteritems() ,可以用于 for 来循环遍历。

  1. 筛选出集合中满足条件的元素

集合解析:找到集合中能被三整除的元素

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n29" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
data={randint(-10,10) for _ in range(10)} #创建集合为{}
data1={x for x in data if x % 3 == 0}
print(data1)</pre>

2-2 如何元组中的元素命名,提高程序的可读性。

学生信息系统中数据为固定格式:(名字,年龄,性别,邮箱地址)

学生数量很大为了减小存储开销,对每个学生信息用元组表示:

(‘Jim',16, 'male','jim8721@gmail.com')

('Lilei',17,'male','leile@qq.com')

('Lucky',16,'female','lucy123@yahoo.com')

访问时,我们使用引索(index)访问,大量引索降低程序可读性,如何解决这个问题。所以我们将索引赋值给能够具体描述索引信息的变量。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n37" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">student=('jim',16,'male','jim8721@gmail.com')
NAME,AGE,SEX,EMAIL=range(4) #将数值分别赋值给四个变量
print(student[NAME])
if student[AGE]>=18:
print(student[NAME],student[AGE])
if student[SEX]=="male":
print(student[NAME],student[SEX])
​</pre>

下面使用类对象来对数据进行访问

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n39" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from collections import namedtuple
student=namedtuple('Student',['name','age','sex','email'])# 创建一个名叫student的类
s=student("jim","16","male","jim8721@gmail.com")# 创建一个student的实例对象
print(s)
print(s.name)#以属性来对s进行访问。
print(s.sex)
print(s.age)
print(isinstance(s,tuple))#检查我们创建的s是否确实是元组
​</pre>

2-3 如何统计出元素出现的频度

实际案列:

1.某随机序列[12,5,4,6,7,8,...]中,找到出现次数出现最多的元素。

知识拓展:

根据键或者值对字典进行排序:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n46" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
data=[randint(0,20) for _ in range(30)]
print(data)
c=dict.fromkeys(data,0)
print(c)
for x in data:
c[x]+=1
print(c)
c_s=sorted(c.keys())
print(c_s)
c_ss=sorted(c.items(),key=lambda item:item[1])
print(c_ss)z

根据键来进行排序

d={'lilee':25,'wanyuan':21,'liqun':32}
sorted(d.keys())

根据值来进行排序

sorted(d.items(),key=lambda item:item[1])
​</pre>

使用Counter 函数来分析:将序列传入Counter 的构造器,得到Counter 对象是元素频数的字典。然后使用Counter.most_common() 方法得到频数最高的n个元素的列表。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n48" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from collections import Counter
from random import randint
data=[randint(0,20) for _ in range(30)]
c2=Counter(data) #统计每个数出现的频数,并返回字典,键是数字,值是数字出现的频数
print(c2)
print(c2.most_common(3))#输出出现次数最多的三个元素</pre>

2.对某英文文章的单词,进行词频统计,找到出现次数最高的10个单词,它们出现的次数是多少。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n51" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from collections import Counter
import re
file="English.txt" #创建一个文件
f=open(file,'w+') #打开文件
f.write("It's quite common those days for students in many contries to have break from studying after graduating from high school. This trend is not restricted for rich students who have money to trival, but is also evident for poorer students who choose to work or become economically independent for a period of time. This trend maybe involve the recognizatiion that young adult who passed directly from school to university is rather restricted in term of general knowledge and experience of the world. On the contrary, those who have spent some time earning a living or travel to other places, have a broader view of life and better personal resource to draw on. They tend to be more independent, which is a very important factor in academic study and research, and giving them an advantage in terms of dealing with the challenges of students' life.")#往文件中写入东西
f.close()# 关闭文件

file=open("English.txt","r")
text=file.read()
txtlist=re.split('\W+',text)#这里使用非单词的字符来进行分割,就可以吧一个一个的单词分开。
c3=Counter(txtlist) #将分割好的单词列表传递给Counter开始计数,最后以字典的形式返回
print(c3)
print(c3.most_common(3)) #输出频度最高的单词</pre>

2-4 如何根据字典中值的大小对字典中的项进行排序

实际案例:

某班英语成绩以字典的形式进行存储:{'lili':79,'lini':88,'dd':90}

现在要求根据成绩的高低,对学生进行排名。

使用python的内置函数sorted

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n58" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
d={x: randint(60,100) for x in 'xyzcfd'}
print(sorted(d)) #只是对键进行了排序,因为键是可迭代对象
print((97,'a') > (100,'b')) #对元组进行比较的时候,先比较低零个元素
socres=list(zip(d.values(),d.keys())) #zip可以对两个列表中的元素进行两两拼接,拼接为(value,key),就可以根据元组的比较来进行排序
print(scores)
print(sorted(scores)) </pre>

利用sorted 函数的key 参数

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n61" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint
d={x: randint(60:100) for x in 'xvgdkuf'}
print(d.items())
print(sorted(d.items(),key=lambda x: x[1])) #使用sorted的key参数时,我们构建一个匿名函数,因为每次穿进去的x值有两项,第零项是键也就是人名,不是我们需要比较的项,而我们需要比较的项是第二项分数,所有就取x[1]</pre>

2-5 如何快速找到多个字典中的公共键

实际案例:西班牙足球甲级联赛,每轮球员进球统计,然后统计出前N轮,每场比赛都有进球的球员。

方法一:对键进行迭代

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n66" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint,sample
s1={x: randint(1,4) for x in sample('abcdefg', randint(3,6))}
s2={x: randint(1,4) for x in sample('abcdefg', randint(3,6))}
s3={x: randint(1,4) for x in sample('abcdefg', randint(3,6))}
print(s1)
print(s2)
print(s3)
res=[]
for k in s1:
if k in s2 and k in s3:
res.append(k)
print(res)</pre>

方法二:利用集合(set)的交集操纵:

  • Step1:使用字典的viewkeys()方法,得到一个字典keys的集合

  • Step2:使用map函数,得到所有的字典的keys 的集合

  • Step3:使用reduce函数,去所有字典的keys的集合的交集

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n75" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from random import randint,sample
s1={x: randint(1,4) for x in sample('abcdefg',randint(3,6))}
s2={x: randint(1,4) for x in sample('abcdefg',randint(3,6))}
s3={x: randint(1,4) for x in sample('abcdefg',randint(3,6))}
print(s1)
print(s2)
print(s3)
print(s1.keys() & s2.keys() & s3.keys())</pre>

但是前面的方法只能针对比赛轮数少的人来说:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n77" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">from functools import reduce #python3中将reduce函数放到了functools中
from random import randint,sample
s1={x: randint(1,4) for x in sample('abcdefg',randint(3,6))}
s2={x: randint(1,4) for x in sample('abcdefg',randint(3,6))}
s3={x: randint(1,4) for x in sample('abcdefg',randint(3,6))}
print(s1)
print(s2)
print(s3)
dd=list(map(dict.keys,[s1,s2,s3]))
print(list(reduce(lambda a,b: a & b, dd)))</pre>

2-6 如何让字典保持有序?

实际案列:某编程竞赛系统,对参赛选手编程解题进行计时,选手完成题目之后,把该选手解题用时记录到字典中,以便赛后安选手名字查询成绩(答题时间越短,成绩越优异)

{'li':(2,43),'mm':(5,52)....}

比赛结束后,需按照排名顺序依次打印选手的成绩,如何实现?

解决方案:使用collections.OrderedDict , 以OrderedDict 代替内置字典Dict,依次将选手的成绩存入OrderedDict。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n83" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># python内置的字典
d={}
d['Jim']=(1,35)
d['Leo']=(2,37)
d['Bob']=(3,40)
for k in d:
print(k) # python内置的字典会默认按照字母的先后顺序来进行输出,而不能发保证字典中的项按照输入的先后顺序来进行排序

使用collections下的OrderedDict来创建的字典:

d=OrderedDict()
d['Jim']=(1,35)
d['Leo']=(2,37)i
d['Bob']=(3,40)
for k in d:
print(k) # 此时输出的键就是按照输入字典的先后顺序来排列的</pre>

具体模拟比赛的过程:(file.py)

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n85" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#!/usr/bin/python2
from time import time
from random import randint
from collections import OrderedDict
players=list('ABCDEFGH') #8个比赛成员用字母代替
start=time() #随机确定开始时间
d=OrderedDict() #创建一个可以排序的字典
for i in xrange(8):
raw_input() #根据输入的事件不同,来等待时间
p=players.pop(randint(0,7-i)) #随机取出player列表中的人名
end=time() 取结束后的时间
print i + 1, p, end-start,
d[p]=(i + 1, end-start)
print("\n")
print("-" * 20)
for k in d:
print k,d[k]
</pre>

如何实现用户的历史记录功能(最多有n条)

很多应用程序都有浏览用户记录的功能,例如:

浏览器可以查看最近访问的网页

视频播放器可以查看最近播放过的视频文件

Shell可以查看用户输入过的命令

。。。。。。

我们现在制作了一个简单的猜数字小游戏,然后添加历史记录的功能,显示用户最近添加过的数字:

实现过程:

使用容量为n的队列存储历史记录:

使用标准库collections中的deque, 它是一个双端循环队列。

程序退出前,可以使用pickle将队列对象存入文件,再次运行程序时将其导入

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n98" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#!/usr/python2
from random import randint
from collections import deque
import pickle
history=deque([],5) #创建一个空的双端队列,然后在之后使用append方法将输入过的值添加到里面去
N = randint(0,100)
def guess(k):
if k == N:
print('right')
return True
if k < N:
print('%s is less than N')
else:
print('%s is greater than N')
return False

while True:
line=raw_input('please input a number:')
if line.isdigit():
k=int(line)
history.append(k)
if guess(k):
break
elif line == 'history' or line == 'h?': #当我们输入特定history的时候就会跳出历史输入记录
print(list(history))
pickle.dump(history,open('history','w'))
q=pickle.load(open('history'))
print(q)</pre>

<mark style="box-sizing: border-box; background: rgb(255, 255, 0); color: rgb(0, 0, 0);">Notice</mark> collections 中的双端队列能够不断更新队列中的内容

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,286评论 0 10
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,730评论 0 8
  • 常用模块 认识模块 什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文...
    go以恒阅读 1,935评论 0 6
  • 1. 选教程 看到crossin的编程教室python教程还不错。以这个为主要学习内容。 python简单实验...
    青岛大桥_Android到后端阅读 562评论 0 0
  • http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的J...
    燕京博士阅读 7,546评论 1 118