黑马程序员技术交流社区
标题:
Python之学习笔记(高级特性)
[打印本页]
作者:
易大帅
时间:
2017-3-15 10:10
标题:
Python之学习笔记(高级特性)
Python之学习笔记-高级特性(c602273091)
[TOC]
切片,迭代,列表表达式,生成器
高级特性
# -*- coding: utf-8 -*-from collections import IterableL = []n = 1while n <= 99: L.append(n) n = n + 2#print L#切片操作L = range(100)#print L[1:20] #和Matlab一样'''前10个数,每两个取一个:>>> L[:10:2][0, 2, 4, 6, 8]所有数,每5个取一个:>>> L[::5][0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]甚至什么都不写,只写[:]就可以原样复制一个list:>>> L[:][0, 1, 2, 3, ..., 99]'''#迭代操作:就是循环而已#print isinstance(123, Iterable)'''dict迭代的是key。如果要迭代value,可以用for value in d.itervalues(),如果要同时迭代key和value,可以用for k, v in d.iteritems()。进行下标和数据同时迭代:>>> for i, value in enumerate(['A', 'B', 'C']):... print i, value...0 A1 B2 C判断某种数据类型是不是可以迭代>>> from collections import Iterable>>> isinstance('abc', Iterable) # str是否可迭代True>>> isinstance([1,2,3], Iterable) # list是否可迭代True>>> isinstance(123, Iterable) # 整数是否可迭代False引用了两个变量>>> for x, y in [(1, 1), (2, 4), (3, 9)]:... print x, y...1 12 43 9'''#列表生成器'''1、>>> [x * x for x in range(1, 11)][1, 4, 9, 16, 25, 36, 49, 64, 81, 100]2、>>> [x * x for x in range(1, 11) if x % 2 == 0][4, 16, 36, 64, 100]3、全排列可以使用两层循环,可以生成全排列:>>> [m + n for m in 'ABC' for n in 'XYZ']['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']4、显示目录名>>> import os # 导入os模块,模块的概念后面讲到>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']5、for循环其实可以同时使用两个甚至多个变量,比如dict的iteritems()可以同时迭代key和value:>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }>>> for k, v in d.iteritems():... print k, '=', v... y = Bx = Az = C列表生成式也可以使用两个变量来生成list:>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }>>> [k + '=' + v for k, v in d.iteritems()]['y=B', 'x=A', 'z=C']最后把一个list中所有的字符串变成小写:>>> L = ['Hello', 'World', 'IBM', 'Apple']>>> [s.lower() for s in L]['hello', 'world', 'ibm', 'apple']思考:如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,所以列表生成式会报错:>>> L = ['Hello', 'World', 18, 'Apple', None]>>> [s.lower() for s in L]Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'int' object has no attribute 'lower'使用内建的isinstance函数可以判断一个变量是不是字符串:>>> x = 'abc'>>> y = 123>>> isinstance(x, str)True>>> isinstance(y, str)False请修改列表生成式,通过添加if语句保证列表生成式能正确地执行。'''#生成器(generator)'''第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:>>> L = [x * x for x in range(10)]>>> L[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g = (x * x for x in range(10))>>> g<generator object <genexpr> at 0x104feab40>创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?如果要一个一个打印出来,可以通过generator的next()方法:>>> g = (x * x for x in range(10))>>> for n in g:... print n第二种方法:最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。generator是非常强大的工具,在Python中,可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator。要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。'''def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1for n in fib(6): print ndef f(x): return x*x#print map(f,range(9))'''reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算'''def add(x,y): return x+yL = range(100)#print reduce(add, L)# 整数和字符串的转换def chr2num(s): return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
def fn(x,y): return 10*x+y#print map(chr2num,'12345')#print reduce(fn,map(chr2num,'12345'))def str2int(s): def fn(x, y): return x * 10 + y def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
return reduce(fn, map(char2num, s))L = range(100)def get_list(x,y): L = [] n = 0 while n < y: L.append(x) n = n + 1 return L#print get_list(3)def prod2(x,y): return sum(get_list(x,y))#print prod2(2,3)def prod(*s): return reduce(prod2,s)L = range(100)L1 = L[1:6]#print prod(*L1)#首字母大写def get_right_name1(x): return x.capitalize()def get_right_name2(x): return x.title()def get_right_name2(x): return x.title()def get_right_name3(x): y = x.lower() y = y[0].upper() + y[1:] return y#print map(get_right_name3,['HHHHHHH']) #这里需要写成列表,因为'HHHH'在map下会一个个被取出#排序'''sorted()函数就可以对list进行排序:>>> sorted([36, 5, 12, 9, 21])[5, 9, 12, 21, 36]sorted()函数也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。比如,如果要倒序排序,我们就可以自定义一个reversed_cmp函数def reversed_cmp(x, y): if x > y: return -1 if x < y: return 1 return 0传入自定义的比较函数reversed_cmp,就可以实现倒序排序:>>> sorted([36, 5, 12, 9, 21], reversed_cmp)[36, 21, 12, 9, 5]我们再看一个字符串排序的例子:>>> sorted(['bob', 'about', 'Zoo', 'Credit'])['Credit', 'Zoo', 'about', 'bob']默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以:'''def ignore_upper(s1,s2): u1 = s1.lower() u2 = s2.lower() if u1 > u2: return 1 elif u1 < u2: return -1 else: return 0#print sorted(['Za','a','dff'],ignore_upper)# filter函数的使用# 和map()类似,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,# 然后根据返回值是True还是False决定保留还是丢弃该元素。# 可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。# filter函数有一个过滤函数,满足这个条件的话就留住def is_sushu(x): L = range(x) if x > 2: for n in L[2:x]: if x%n == 0: return True else: pass elif x == 2: return False else: return True return FalseL = range(101)#print filter(is_sushu,L[1:101])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
作者:
zzxt
时间:
2017-6-18 20:15
这是什么····
作者:
lanqi0820
时间:
2018-5-28 14:59
编辑的时候注意下各式就好了,看着也不会费劲
作者:
baby14
时间:
2018-5-30 09:18
有点费劲
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2