python的高级特性:切片,迭代,列表生成式,生成器,迭代器
1 #演示切片 2 k="abcdefghijklmnopqrstuvwxyz" 3 #取前5个元素 4 k[0:5] 5 k[:5] 6 #后5个元素 7 k[-5:] #vwxyz 8 #每隔一个取一个 9 k[::2] #acegikmoqsuwy 10 #原样复制一个 11 k[:] 12 13 #演示迭代 14 d={'a':1,'b':2,'c':3} 15 for key in d: 16 print(key) 17 #结果输出abc, 即输出key, 而且要注意dict的迭代顺序不像list是顺序排列的 18 19 for v in d.values(): 20 print(v) 21 #按值输出, 1,2,3 22 23 for k,v in d.items(): 24 print(k+":"+str(v)) 25 #按键值对输出,a:1,b:2,c:3 26 27 ary=range(10) 28 for i,v in enumerate(ary): 29 print(str(i)+" "+str(v)) 30 #enumerate函数可以把一个list变为索引元素对,这样我们迭代元素就可以同时取得索引 31 32 for x,y in [(1,1),(2,4),(3,7)]: 33 print(x,y) 34 #for循环里,引用两个变量是比较常见的 35 36 37 #下面演示 列表生成式 38 k=list(range(1,11)) 39 print(k) 40 #显示 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 41 42 k=[x*x for x in range(1,11)] 43 print(k) 44 #显示 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 45 46 k=[x*(x+1) for x in range(1,11,2)] 47 print(k) 48 #显示 [2, 12, 30, 56, 90] 49 50 #在列表生成器中我们还可以在后面附加if条件语句 51 def toUppers(L): 52 return [x.upper() for x in L if isinstance(x,str)] 53 54 print(toUppers(['hello','world',100])) 55 #显示 ['HELLO', 'WORLD'] 56 57 58 #在列表生成式中,也可以用多层 for 循环来生成列表 59 print([m*100+n*10+z for m in range(1,10) for n in range(0,10) 60 for z in range(1,10) if m*100+n*10+z==z*100+n*10+m]) 61 62 #结果 63 #[101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 64 # 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 65 # 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 66 # 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 67 # 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 68 # 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999] 69 70 print([m+n for m in 'ABC' for n in 'XYZ']) 71 #结果 ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ'] 72 73 #列出当前目录下的所有文件与目录名 74 import os 75 print([d for d in os.listdir('.')]) 76 77 #下面演示 生成器 78 #生成器类似于C#中的滞后执行机制,只在迭代时占用资源。其目的是不会一次把 79 #100万个列表一次载入内存。 80 list1=[x*x for x in range(10)] 81 print(list1) 82 #输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 83 84 #下面的g就是一个生成器 generator 85 g=(x*x for x in range(10)) 86 print(g) 87 #输出 <generator object <genexpr> at 0x0000021FAC0A3B48> 88 #如果要输出generator的每个元素,可以用next()函数 89 print(next(g)) #0 90 print(next(g)) #1 91 print(next(g)) #4 92 #正常的方式还是使用forgrgi循环迭代对象 93 for n in g: 94 print(n) 95 96 #斐波拉契数列生成的函数 97 def fib(max): 98 n,a,b=0,0,1 99 while n<max: 100 print(b) 101 a,b=b,a+b 102 n=n+1 103 return 'done' 104 fib(6) 105 #输出 1 1 2 3 5 8 106 107 #我们把上面的函数改成generator, 只需要把print(b) 改为yield b 108 #这就是定义generator的另一种方法,一个函数中包含yield关键字,它就不 109 #是一个普通函数,而是一个generator 110 def fib(max): 111 n,a,b=0,0,1 112 while n<max: 113 yield b 114 a,b=b,a+b 115 n=n+1 116 return 'done' 117 118 f=fib(6) 119 print(f) 120 #输出 <generator object fib at 0x000001F82E3C3C50> 121 122 #用for循环generator时,会发现拿不return的返回值,其实必须要捕获 123 #StopIteration错误,才可以。 124 g=fib(6) 125 while True: 126 try: 127 x=next(g) 128 print('g:',x) 129 except StopIteration as e: 130 print('Generator return value:',e.value) 131 break; 132 133 #输出 134 #g: 1 135 #g: 1 136 #g: 2 137 #g: 3 138 #g: 5 139 #g: 8 140 #Generator return value: done 141 142 #再举一个简单的例子,可以看到generator的执行流程 143 def odd(): 144 print('step1') 145 yield 1 146 print('step2') 147 yield (3) 148 print('step3') 149 yield (5) 150 151 #调用 152 o=odd() 153 next(o) #step1 154 next(o) #step2 155 next(o) #step3 156 #next(o) #StopIteration 157 158 #总结一下: 159 #能用于for循环的类型有 160 #(一)集合类型 list,tuple,dict,set,str等 161 #(二) generator, 包括生成器和带yield的generator function 162 #这些对象统称为可迭代的对象: Iterable 163 164 #可以使用isinstance判断一个对象是否是Iterable对象: 165 from collections import Iterable 166 print(isinstance([],Iterable)) #True 167 print(isinstance('abc',Iterable)) #True 168 print(isinstance(100,Iterable)) #False 169 170 #而可以被next()函数调用并不断返回下一个值的对象称为迭代器 Iterator 171 #可以使用isinstance()判断是否为Iterator对象 172 from collections import Iterator 173 print(isinstance((x for x in range(10)),Iterator)) 174 print(isinstance([2,3,4],Iterator)) 175 176 #生成器都是Iterator对象,但是list,dict,str虽然是Iterable,去不是Iterator 177 #把list,dict,str转为Iterator可以使用iter()函数 178 print(isinstance(iter('abcdefg'),Iterator)) 179 #结果 True 180 181 #Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是不可能存储全体自然数的