python高级编程1
Posted 杨-先森
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python高级编程1相关的知识,希望对你有一定的参考价值。
1.如何在列表,字典,集合中根据条件筛选数据?
如:
过滤列表[3, 9, -1, 10, 20, -2...]中的负数
筛出字典{‘小明’:70, ‘Jim‘:88,‘Tom‘:98...}中值高于90的项
筛出集合(2,3,5,7,8,12,23...)中能被3整除的元素
像第一种过滤列表中的负数,有一种通用的方法
data = [1,2,-1,-4,3,5,6] result = [] for x in data: if x >= 0: result.append(x) print result
在python中我们可以使用高级的工具,如:
列表 | filter函数 | filter(lambda x:x >=0, data) |
列表解析 | [x for x in data if x>=0] | |
字典 | 字典解析 | {k : v for k, v in d.iteritems() if v > 90} |
集合 | 集合解析 | {x for x in s if x%3 ==0} |
在列表中筛选大于等于零的方法:
第一种方式:
In [1]: from random import randint In [2]: data = [randint(-10, 10)for _ in xrange(10)] In [3]: data Out[3]: [-8, 3, 6, 9, -1, 10, 3, 4, -7, -9] In [4]: filter(lambda x: x>=0,data) Out[4]: [3, 6, 9, 10, 3, 4]
第二种方式:
In [5]: [x for x in data if x >= 0] Out[5]: [3, 6, 9, 10, 3, 4]
比较两种方式哪种好
In [6]: timeit filter(lambda x: x>=0,data) 1000000 loops, best of 3: 1.22 µs per loop In [7]: timeit [x for x in data if x >= 0] 1000000 loops, best of 3: 546 ns per loop
由此得出列表解析快出filter函数,但两者方式速度都高于上面的通用方法
在字典中筛选元素
In [13]: d = {x: randint(60,100) for x in xrange(1,20)} In [14]: d Out[14]: {1: 90, 2: 91, 3: 97, 4: 77, 5: 77, 6: 86, 7: 87, 8: 92, 9: 81, 10: 91, 11: 74, 12: 80, 13: 88, 14: 96, 15: 82, 16: 83, 17: 93, 18: 66, 19: 73} In [15]: {k : v for k,v in d.iteritems() if v > 90} Out[15]: {2: 91, 3: 97, 8: 92, 10: 91, 14: 96, 17: 93}
在集合中筛选符合条件的
In [16]: data Out[16]: [-8, 3, 6, 9, -1, 10, 3, 4, -7, -9] In [17]: s = set(data) In [18]: s Out[18]: {-9, -8, -7, -1, 3, 4, 6, 9, 10} In [19]: {x for x in s if x % 3 == 0} Out[19]: {-9, 3, 6, 9}
2.如何为元祖中的每个元素命名,提高程序的可读性
如:
学生管理系统中数据为固定格式:
(名字,年龄,性别,邮箱地址,...)
学生数量很大为了减小存储开销,对每个学生信息用元祖表示:
(‘Jim‘, 16, ‘male‘, ‘[email protected]‘)
(‘Tom‘, 17, ‘male‘, ‘[email protected]‘)
...
访问时,我们使用索引访问,大量索引降低了可读性,如何解决这个问题呢?
如:
In [20]: student = (‘Jim‘, 16, ‘male‘, ‘[email protected]‘) #name In [22]: print student[0] Jim #age In [23]: print student[1] 16 #sex In [24]: print student[2] male #email In [25]: print student[3] [email protected]
第一种方法可以定义常量,如:
In [26]: Name = 0 In [27]: Age = 1 In [28]: Sex = 2 In [29]: Email = 3 ... #Name,Age,Sex,Email = xrange(4)
In [30]: student = (‘Jim‘, 16, ‘male‘, ‘[email protected]‘) In [32]: print student[Name] Jim In [33]: print student[Age] 16 ...
第二种方案:使用标准库中collections.namedtuple替对内置tuple
In [37]: from collections import namedtuple In [38]: Student = namedtuple(‘Student‘, [‘name‘, ‘age‘, ‘sex‘, ‘email‘]) In [39]: s = Student(‘Jim‘, 16, ‘male‘, ‘[email protected]‘) In [40]: s Out[40]: Student(name=‘Jim‘, age=16, sex=‘male‘, email=‘[email protected]‘) In [41]: s2 = Student(name=‘Jim‘, age=16, sex=‘male‘, email=‘[email protected]q.com‘) In [42]: s2 Out[42]: Student(name=‘Jim‘, age=16, sex=‘male‘, email=‘[email protected]‘) In [43]: s.name Out[43]: ‘Jim‘ In [44]: s.age Out[44]: 16
...
3.如何统计序列中元素的出现频度?
如:1.某随机序列[1,3,2,6,7,11,...]中,找到出现次数最高的3个元素,它们出现的次数是多少?
2.对某英文文章的单词,进行词频统计,找到出现次数最高的10个单词,他们出现的次数是多少?
方法一.可以使用字典的方法
In [1]: from random import randint In [2]: data = [randint(0,20) for _ in xrange(30)] In [3]: data Out[3]: [10, 19, 13, 13, 4, 5, 15, 3, 4, 0, 8, 17, 19, 3, 18, 3, 19, 4, 14, 13, 3, 8, 2, 18, 7, 17, 9, 7, 13, 4] In [4]: dict1 = {}.fromkeys(data,0) In [5]: for x in data: ...: dict1[x] += 1 ...: In [6]: dict1 Out[6]: {0: 1, 2: 1, 3: 4, 4: 4, 5: 1, 7: 2, 8: 2, 9: 1, 10: 1, 13: 4, 14: 1, 15: 1, 17: 2, 18: 2, 19: 3}
方法二.使用collections.Counter对象,将序列传入Counter的构造器,得到Counter对象是元素频度的字典,Counter.most_common(n)方法得到频度最高的n个元素的列表
In [9]: data1 = Counter(data) In [10]: data1 Out[10]: Counter({0: 1, 2: 1, 3: 4, 4: 4, 5: 1, 7: 2, 8: 2, 9: 1, 10: 1, 13: 4, 14: 1, 15: 1, 17: 2, 18: 2, 19: 3}) In [11]: data1.most_common(3) Out[11]: [(3, 4), (4, 4), (13, 4)]
#统计英语文章单词 In [20]: import re In [21]: txt = open(‘a.txt‘).read() In [22]: txt Out[22]: ‘Anti Tracks is a complete solution to protect your privacy and enhance ....‘ In [23]: re.split(‘\W+‘,txt) Out[23]: [‘Anti‘, ‘Tracks‘, ‘is‘, ‘a‘, ‘Tracks‘, ‘securely‘, ...}) In [26]: c.most_common() Out[26]: [(‘and‘, 5), (‘Tracks‘, 4), (‘your‘, 4), (‘Anti‘, 4), (‘erasing‘, 3), (‘to‘, 3), (‘computer‘, 2), (‘privacy‘, 2), (‘support‘, 2), (‘more‘, 2), ...] In [27]: c.most_common(10) Out[27]: [(‘and‘, 5), (‘Tracks‘, 4), (‘your‘, 4), (‘Anti‘, 4), (‘erasing‘, 3), (‘to‘, 3), (‘computer‘, 2), (‘privacy‘, 2), (‘support‘, 2), (‘more‘, 2)]
4.如何根据字典中的值的大小,对字典中的项排序
如:某班英语成绩以字典的形式存储:
{‘Limei‘:90, ‘Tom‘:89,...}
根据成绩高低,计算成绩排名
方法一.利用zip将字典转换为元祖,再用sorted方法
In [29]: from random import randint In [30]: d = {x:randint(70,100) for x in ‘abcd‘} In [31]: d Out[31]: {‘a‘: 94, ‘b‘: 85, ‘c‘: 87, ‘d‘: 94} In [33]: zip(d.values(), d.keys()) Out[33]: [(94, ‘a‘), (87, ‘c‘), (85, ‘b‘), (94, ‘d‘)] #使用迭代方法节省空间 In [34]: zip(d.itervalues(), d.iterkeys()) Out[34]: [(94, ‘a‘), (87, ‘c‘), (85, ‘b‘), (94, ‘d‘)] In [35]: sorted(zip(d.itervalues(), d.iterkeys())) Out[35]: [(85, ‘b‘), (87, ‘c‘), (94, ‘a‘), (94, ‘d‘)]
方法二.传递sorted函数的key参数
In [36]: d.items() Out[36]: [(‘a‘, 94), (‘c‘, 87), (‘b‘, 85), (‘d‘, 94)] In [37]: sorted(d.items(), key=lambda x :x[1] ) Out[37]: [(‘b‘, 85), (‘c‘, 87), (‘a‘, 94), (‘d‘, 94)]
5.如何快速找到多个字典的公共键(key)?
如:足球联赛,每轮球员的进球统计:
第一轮:{‘梅西‘:2,‘贝尔‘:2...}
第二轮:{‘梅西‘:1,‘贝尔‘:1...}
...
统计出前N轮,每场比赛都有进球的球员
方法一.将相同的键添加到列表中
In [38]: from random import randint, sample #使用sample,产生随机进球的球员 In [39]: sample(‘abcdefg‘, randint(3,6)) Out[39]: [‘d‘, ‘c‘, ‘b‘] In [40]: s1 = {x:randint(1,3) for x in sample(‘abcdefg‘, randint(3,6))} In [41]: s2 = {x:randint(1,3) for x in sample(‘abcdefg‘, randint(3,6))} In [42]: s3 = {x:randint(1,3) for x in sample(‘abcdefg‘, randint(3,6))} In [43]: s1 Out[43]: {‘c‘: 3, ‘d‘: 3, ‘f‘: 1} In [44]: s2 Out[44]: {‘b‘: 2, ‘d‘: 1, ‘f‘: 1} In [45]: s3 Out[45]: {‘c‘: 2, ‘d‘: 3, ‘e‘: 2, ‘f‘: 1, ‘g‘: 3} In [46]: result = [] In [47]: for key in s1: ...: if key in s2 and key in s3: ...: result.append(key) ...: In [48]: result Out[48]: [‘d‘, ‘f‘]
方法二.利用集合(set)的交集操作
1.使用字典的viewkeys()方法,得到一个字典keys的集合
In [49]: s1.viewkeys() Out[49]: dict_keys([‘c‘, ‘d‘, ‘f‘]) In [50]: s2.viewkeys() Out[50]: dict_keys([‘b‘, ‘d‘, ‘f‘]) In [51]: s3.viewkeys() Out[51]: dict_keys([‘c‘, ‘e‘, ‘d‘, ‘g‘, ‘f‘]) In [53]: s1.viewkeys() & s2.viewkeys() & s3.viewkeys() Out[53]: {‘d‘, ‘f‘}
2.使用map函数,得到所有字典的keys集合
3.使用reduce函数,取所有字典的keys的集合的交集
In [55]: map(dict.viewkeys, [s1,s2,s3]) Out[55]: [dict_keys([‘c‘, ‘d‘, ‘f‘]), dict_keys([‘b‘, ‘d‘, ‘f‘]), dict_keys([‘c‘, ‘e‘, ‘d‘, ‘g‘, ‘f‘])] In [56]: reduce(lambda a,b:a&b, map(dict.viewkeys, [s1,s2,s3])) Out[56]: {‘d‘, ‘f‘}
6.如何让字典保持有序?
如:某答题比赛,对选手进行计时,答完题目后,用字典的形式保存,以便赛后按选手名查询成绩,(答题时间越短,成绩越优)
{‘Limei’:(2,43), ‘Tom‘:(1,20),...}
比赛结束后,需要按照成绩打印名次,如何实现?
方法.使用collections中的OrderedDict替代内置Dict,依次将选手成绩存入OrderedDict
In [57]: from collections import OrderedDict In [61]: d[‘a‘] = (1,23) In [62]: d[‘b‘] = (2,25) In [63]: d[‘c‘] = (3,30) In [64]: for key in d: ...: print key ...: a b c
问题代码
from time import time from random import randint from collections import OrderedDict player = list(‘abcdef‘) d = OrderedDict() start = time() for x in xrange(0,6): raw_input() p = player.pop(randint(0,5-x)) end = time() print x+1, p, end-start d[p] = (x+1, end-start) print ‘-‘*20 for key in d: print key ,d[key]
7.如何实现用户的历史记录功能(最多n条)?
如:浏览器可以查看最近的访问过的网页
shell可以查看用户输入过的命令
现在我们制作一个猜数字游戏,来添加历史记录功能,显示用户最近猜测的数据
方法.使用容量为n的队列存储历史记录,使用标准库collections中的deque,它是一个双端循环队列,程序退出前,可以使用pickle将队列对象存入文件,再次运行程序时将其导入
from random import randint from collections import deque N = randint(0,100) history = deque([], 5) def guess(k): if k == N: print ‘right‘ if k < N: print ‘%s is less than N‘% k if k > N: print ‘%s is greater than N‘% k 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?‘: print list(history)
In [66]: from collections import deque In [67]: q = deque([],3) In [68]: q.append(3) In [69]: q.append(4) In [70]: q.append(8) In [71]: q Out[71]: deque([3, 4, 8]) In [72]: import pickle In [73]: pickle.dump(q, open(‘a.txt‘,‘w‘)) In [74]: open(‘a.txt‘).read() Out[74]: ‘ccollections\ndeque\np0\n((lp1\nI3\naI4\naI8\naI3\ntp2\nRp3\n.‘ In [75]: q1 = pickle.load(open(‘a.txt‘)) In [76]: q1 Out[76]: deque([3, 4, 8])
以上是关于python高级编程1的主要内容,如果未能解决你的问题,请参考以下文章
Python高级编程(第2版) 中文完整pdf扫描版[76MB]