python3入门笔记三之高级特性---切片,迭代,列表生成式,生成器,迭代器

558 阅读6分钟

这是我参与更文挑战的第20天,活动详情查看: 更文挑战

切片 (取指定索引范围 )

格式: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 都可以遍历

  1. 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)
    
    
  2. demo-string: 在es6中这个也可以直接遍历,可以参考博主的这篇文章《es6入门提升总结一之字符串的遍历器接口》 es6写法:for (let codePoint of 'foo') {}

    for ch in 'HelloWorld':
        print(ch)
    
  3. 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     
    
  4. 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))

  1. 生成[1x1, 2x2, 3x3, ..., 10x10]格式
print([x*x for x in range(1,11)])
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
  1. 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]

  1. 还可以使用两层循环,可以生成全排列:
print([m+n for m in 'abc' for n in 'xyz'])
# ['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']
  1. 列出当前目录下的所有文件和目录名,可以通过一行代码实现
import os
print([d for d in os.listdir('.')])
# ['hello-world', 'notebook.ipynb', 'python入门笔记2和3.ipynb']

生成器 (generator)

这个看着也有点眼熟, 哈哈 原来在es6中也有这个generator

在Python中,这种一边循环一边计算的机制,称为生成器:generator。

有了生成器,我们可以在需要的时候才去创建这个元素出来,可以节省内存的使用 定义 generator 的一种方法:将一个列表生成式的 [] 改成 () 20200719150455

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:

20200719145216

最难理解的就是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的计算是惰性的,只有在需要返回下一个数据时它才会计算。

20200719154840

最后

如果你觉得本篇文章还不错的话,那 拜托再点点赞 支持一下呀😝

让我们开始这一场意外的相遇吧!~

欢迎留言!谢谢支持!ヾ(≧▽≦*)o 冲冲冲!!

我是4ye 咱们下期很快再见!!