切片 (取指定索引范围 )
格式:arr[开始索引:结束索引:Step]
开始索引 默认0,可不写; 结束索引默认为数组的长度, 获取的范围为 开始索引-结束索引 之间, 不包括结束索引; Step默认为1。
L = ['0', '1', '2', '3', '4'] print( L[0:3]) # ['0', '1', '2'] 获取从索引0开始,到索引3之间的,不包括索引3的数 print( L[-2:-1]) # ['3'] 从倒数第二个开始到倒数第一个之间 print( L[::2]) # 步长step为2时结果 ['0', '2', '4'] 复制代码
前10个数: L[:10]
后10个数: L[-10:]
10-20之间: L[10:20]
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
print( (0, 1, 2, 3, 4, 5)[:3]) # (0, 1, 2)
字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:print( 'HelloWorld!'[:3]) # Hel
利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法:
def myTrim(s): while(s[:1] == ' '): s = s[1:] while(s[-1:] == ' '): s = s[:-1] return s print(myTrim(' aa ')) 复制代码
迭代 (Iterable)
Python中,迭代是通过for ... in来完成的 使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行
dict ,list ,tuple,string 都可以遍历
- demo-dict :
默认情况下,dict迭代的是key。 如果要迭代value,可以用
for value in d.values()
, 如果要同时迭代key和value,可以用for k, v in d.items()
。
#dict 字典的存储不是按照list的方式顺序排列,所以迭代出的结果顺序很可能不一样。 d = {'a': 1, 'aa': 2, 'c': 3} for key in d: print(key) for value in d.values(): print(value) for key,value in d.items(): print(key,value) 复制代码
- demo-string: 在es6中这个也可以直接遍历,可以参考博主的这篇文章《es6入门提升总结一之字符串的遍历器接口》 es6写法:
for (let codePoint of 'foo') {}
for ch in 'HelloWorld': print(ch) 复制代码
- demo-list:
如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
from collections import Iterable print(isinstance({'a':1,'b':2},Iterable)) # dict True print(isinstance('hello world',Iterable)) # str True print(isinstance([1,2,3,4,5],Iterable)) # list True print(isinstance((1,2,3,4,5,6),Iterable)) # tuple True print(isinstance(111,Iterable)) # num False 复制代码
如果要对list实现类似Java那样的下标循环怎么办?Python内置的 enumerate (枚举)函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i, value in enumerate(['A', 'B', 'C']): print(i, value) # 结果: 0 A 1 B 2 C 复制代码
- demo-tuple:
for (x) in ([1,2],[3,4],[5,6]): print(x) # 结果: [1, 2] [3, 4] [5, 6] # 获取tuple中list的值 for (x,y) in ([1,2],[3,4],[5,6]): print(x,y) # 结果: 1 2 3 4 5 6 复制代码
列表生成式 (List Comprehensions)
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。举个例子,要生成list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以用list(range(1, 11))
:
- 生成
[1x1, 2x2, 3x3, ..., 10x10]
格式
print([x*x for x in range(1,11)]) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 复制代码
- for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
在一个列表生成式中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else
print([x*x for x in range(1,11) if x%2==0]) # [4, 16, 36, 64, 100] print([x if x % 2 == 0 else -x for x in range(1, 11)]) # [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10] 复制代码
- 还可以使用两层循环,可以生成全排列:
print([m+n for m in 'abc' for n in 'xyz']) # ['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz'] 复制代码
- 列出当前目录下的所有文件和目录名,可以通过一行代码实现
import os print([d for d in os.listdir('.')]) # ['hello-world', 'notebook.ipynb', 'python入门笔记2和3.ipynb'] 复制代码
生成器 (generator)
这个看着也有点眼熟, 哈哈 原来在es6中也有这个generator
在Python中,这种一边循环一边计算的机制,称为生成器:generator。
有了生成器,我们可以在需要的时候才去创建这个元素出来,可以节省内存的使用 定义 generator 的一种方法:将一个列表生成式的 [] 改成 ()
g = (x **2 for x in range(10)) print(next(g)) # 0 print(next(g)) # 1 print(next(g)) # 4 print(next(g)) # 9 # 直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。 复制代码
正确的方法是使用for循环,因为generator也是可迭代对象:
g = (x **2 for x in range(10)) for n in g: print(n) 复制代码
定义generator的另一种方法,如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
# 斐波拉契数列 def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done' for a in fib(6): print(a) # 1 1 2 3 5 8 复制代码
注意: a, b = b, a + b 等于 t = (b, a + b) # t是一个tuple a = t[0] b = t[1]
for循环,拿不到这个return 的 'done',如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done' f=fib(6) while True: try: x=next(f) print('g', x) except StopIteration as e: print('Generator return value: ', e.value) break # g 1 # g 1 # g 2 # g 3 # g 5 # g 8 # Generator return value: done 复制代码
迭代器 (Iterator)
看到这个迭代器,就想到在java中,只能通过这个iterator在遍历中删除这个元素,而不能在普通的for循环中去删除这个集合的元素 😄
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
from collections import Iterator print(isinstance((x for x in range(10)),Iterator)) # True print(isinstance([],Iterator)) # False print(isinstance((),Iterator)) # False print(isinstance('a',Iterator)) # False 复制代码
直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list、tuple、dict、set、str等; 一类是generator,包括生成器和带yield的generator function。 这些可以直接作用于for循环的对象统称为可迭代对象:Iterable
上面迭代中的3.demo-list有说到如何判断一个对象是可迭代对象
Iterable 可以通过 iter() 函数转变成 Iterator
from collections import Iterator a=[1,2,3,4,5] b=iter(a) print(isinstance(b, Iterator)) print(next(b)) # 1 复制代码
Iterator对象表示的是一个数据流 Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。