• python基础-------函数(三)


    迭代器

    一、迭代的概念

    迭代:
    1 重复
    2 下一次重复是基于上一次的结果

    l=['a','b','c','d']

    count=0
    while count < len(l):
      print(l[count])
     count+=1

    #循环本身就是一个迭代的过程!

    '''
    python为了提供一种不依赖于索引的迭代方式,
    python会为一些对象内置__iter__方法
    obj.__iter__称为可迭代的对象
    '''

    obj.__iter__() 得到的结果就是迭代器

    得到的迭代器:既有__iter__又有一个__next__方法

     d={'a':1,'b':2,'c':3}
    i=d.__iter__() #i叫迭代器
    # print(i)
    # print(i.__next__())
    # print(i.__next__())
    # print(i.__next__())

    二、迭代器的优缺点

    迭代器的优点
      1:提供了一种不依赖于索引的取值方式
      2:惰性计算。节省内存

    迭代器的缺点:
      1:取值不如按照索引取值方便
      2:一次性的。只能往后走不能往前退
      3:无法获取长度

    判断对象是否为迭代器需要导入模块

    from collections import Iterable,Iterator

    # str1='hello'
    # list1=[1,2]
    # tuple1=(1,2)
    # dic={'a':1}
    # set1={1,2,3}
    # f=open('a.txt','w')

    # print(isinstance(str1,Iterable))
    # print(isinstance(list1,Iterable))
    # print(isinstance(tuple1,Iterable))
    # print(isinstance(dic,Iterable))
    # print(isinstance(set1,Iterable))
    # print(isinstance(f,Iterable))

    三:三元表达式

    由三个元素组成的表达式形式。

    例如:

    x=2

    y=3

    if 2<3:

      print(x)

    else:

      print(y)

    可以直接转换成三元表达式:

    x if x<y else y

    4:列表解析:

    l=[1,31,73,84,57,22]
     l_new=[]
     for i in l:
     if i > 50:
      l_new.append(i)
      print(l_new)

    可以直接:res=[i for i in l  if > 50]

    print(res)#直接输出的就是列表形式的。

    5:生成器表达式

    #[ i for i in range(10000)]

    g=(i for i in range(10000))

    print(g)#这样产生的是一个生成器。

    6:生成器函数:

    #生成器函数:函数体内包含有yield关键字,该函数执行的结果是生成器


    def foo():
      print('first------>')
      yield 1
      print('second----->')
      yield 2
      print('third----->')
      yield 3
      print('fouth----->')

    '''
    yield的功能:
    1.与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次值
    2.为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器
    3.遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的
    '''

    以类似于linuxtaif -f 命令的方式举例

    import time
    def tail(filepath,encoding='utf-8'):
      with open(filepath,encoding=encoding) as f:
      f.seek(0,2)
      while True:
    # f.seek(0, 2) #不行
      line=f.readline()
      if line:
      # print(line,end='')
      yield line
      else:
      time.sleep(0.5)

    g=tail('a.txt')
    print(g)
    print(g.__next__())

    五:面向过程编程:
    编程时先将流程写出,再一个一个去添加内容,将思路流程化。
    这样的好处是思路清晰条理,但是缺点是某一个流程出错,整个程序都会有问题,需要一个阶段一个阶段的拍错修改!
    利用send给yield赋值!
    # def init(func):
    #     def wrapper(*args,**kwargs):
    #         g=func(*args,**kwargs)
    #         next(g)
    #         return g
    #     return wrapper
    #
    # @init #foo=init(foo)
    # def foo():
    #     print('starting')
    #     while True:
    #         x=yield None#return 1
    #         print('value :   ',x)
    # g=foo() #wrapper()
    # g.send(2)
    send的效果:
        # 1:先从为暂停位置的那个yield传一个值,然后yield会把值赋值x
        # 2:与next的功能一样
     
    这样的一个流程也是面向过程编程的应用
    利用yield实现linx命令grep -rl  ‘root’ /etc命令
    应用:grep -rl 'root' /etc
    import os
    def init(func):
        def wrapper(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    #阶段一:递归地找文件的绝对路径,把路径发给阶段二
    @init
    def search(target):
        'search file abspath'
        while True:
            start_path=yield
            g = os.walk(start_path)
            for par_dir, _, files in g:
                # print(par_dir,files)
                for file in files:
                    file_path = r'%s\%s' % (par_dir, file)
                    target.send(file_path)
    #阶段二:收到文件路径,打开文件获取获取对象,把文件对象发给阶段三
    @init
    def opener(target):
        'get file obj: f=open(filepath)'
        while True:
            file_path=yield
            with open(file_path,encoding='utf-8') as f:
                target.send((file_path,f))
     
    #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四
    @init
    def cat(target):
        'read file'
        while True:
            filepath,f=yield
            for line in f:
                res=target.send((filepath,line))
                if res:
                    break
     
    #阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五
    @init
    def grep(target,pattern):
        'grep function'
        tag=False
        while True:
            filepath,line=yield tag #target.send((filepath,line))
            tag=False
            if pattern in line:
                target.send(filepath)
                tag=True
    #阶段五:收到文件名,打印结果
    @init
    def printer():
        'print function'
        while True:
            filename=yield
            print(filename)
     
    start_path1=r'C:UsersAdministratorPycharmProjectspython5期a'
    start_path2=r'C:UsersAdministratorPycharmProjectspython5期a'
    g=search(opener(cat(grep(printer(),'root'))))
     
    print(g)
    # g.send(start_path1)
    g.send(start_path2)
    六:匿名函数

    # def func1(x):
    # return x**2
    # print(func1)


    # func2=lambda x:x**2 #return print('hello')
    # print(func2)

    这样单纯的只是返回值的函数我们用lambda来表示它没有函数名,被称为匿名函数!

    salaries={
    'egon':3000,
    'alex':100000000,
    'wupeiqi':10000,
    'yuanhao':2000
    }
    # def func(x):
    # return salaries[x]


    # print(max(salaries,key=lambda x:salaries[x]))

    # min
    # zip


    # map:映射
    # l=[1,2,3,4]
    # m=map(lambda x:x**2,l)
    # print(list(m))

    # names=['alex','wupeiqi','yuanhao']
    # print(list(map(lambda item:item+'_SB',names)))


    #reduce:合并
    from functools import reduce

    # res=0
    # for i in range(100):
    # res+=1


    # print(reduce(lambda x,y:x+y,range(100),100))

    # filter:过滤
    #
    # names=['alex_sb','yuanhao_sb','wupeiqi_sb','egon']
    # print(list(filter(lambda name:name.endswith('_sb'),names)))

    七、函数的递归

    '''
    递归调用:
    在调用一个函数的过程中,直接或者间接调用了该函数本身

    '''

    # def func():
    # print('====>func')
    # func()
    #
    # func()

     
  • 相关阅读:
    [LeetCode] Range Sum Query
    [LeetCode] Longest Increasing Subsequence
    [LeetCode] Bulls and Cows
    [LeetCode] Serialize and Deserialize Binary Tree
    [LeetCode] Find Median from Data Stream
    [LeetCode] Convert Sorted List to Binary Search Tree
    [LeetCode] Nim Game
    [LeetCode] Word Pattern
    安装配置说明与注意
    java.lang.OutOfMemoryError: PermGen space及其解决方法
  • 原文地址:https://www.cnblogs.com/niubin/p/7020242.html
Copyright © 2020-2023  润新知