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]
View Code

 

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)
View Code

 

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]

Python高级编程(第2版) 中文完整pdf扫描版[76MB]

Python高级编程及应用

python高级编程1

Python高级编程和异步IO并发编程

python高级编程