迭代器

一、迭代的概念

迭代:
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:\Users\Administrator\PycharmProjects\python5期\a'
start_path2=r'C:\Users\Administrator\PycharmProjects\python5期\a\b'
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()

 

python基础-------函数(三)的更多相关文章

  1. Python 基础语法(三)

    Python 基础语法(三) --------------------------------------------接 Python 基础语法(二)------------------------- ...

  2. Python基础学习三

    Python基础学习三 1.列表与元组 len()函数:可以获取列表的元素个数. append()函数:用于在列表的最后添加元素. sort()函数:用于排序元素 insert()函数:用于在指定位置 ...

  3. python基础——函数的参数

    python基础——函数的参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复 ...

  4. python基础—函数嵌套与闭包

    python基础-函数嵌套与闭包 1.名称空间与作用域 1 名称空间分为: 1 内置名称空间   内置在解释器中的名称 2 全局名称空间   顶头写的名称 3 局部名称空间 2 找一个名称的查找顺序: ...

  5. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  6. Python基础-函数参数

    Python基础-函数参数 写在前面 如非特别说明,下文均基于Python3 摘要 本文详细介绍了函数的各种形参类型,包括位置参数,默认参数值,关键字参数,任意参数列表,强制关键字参数:也介绍了调用函 ...

  7. python基础,函数,面向对象,模块练习

    ---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? #  [] {} () None 0 2,位和字节的关系? # ...

  8. Python基础知识(三)

    Python基础知识(三) 一丶整型 #二进制转成十进制的方法 # 128 64 32 16 8 4 2 1 1 1 1 1 1 1 例如数字5 : 101 #十进制转成二进制的方法 递归除取余数,从 ...

  9. 第三章:Python基础の函数和文件操作实战

    本課主題 Set 集合和操作实战 函数介紹和操作实战 参数的深入介绍和操作实战 format 函数操作实战 lambda 表达式介绍 文件操作函数介紹和操作实战 本周作业 Set 集合和操作实战 Se ...

  10. Python基础篇(三)_函数及代码复用

    Python基础篇_函数及代码复用 函数的定义.使用: 函数的定义:通过保留字def实现. 定义形式:def <函数名>(<参数列表>): <函数体> return ...

随机推荐

  1. vue2组件之select2调用

    目前,项目中使用了纯前端的静态项目+RESTFul接口的模式.为了更好的对数据进行操作,前端使用了vue2的mvvm功能,但是由于不是单页面应用,所以,并没有涉及到其它的如vue-route等功能,也 ...

  2. Python学习手册 :Python 学习笔记第一天

    获取当前目录路径: import os os.getcwd() 在输入python程序时,尽量让不是嵌套结构的语句处于最左侧,要不然系统或许会出现"SyntaxError"错误 获 ...

  3. zoj1151 zoj1295 Word Reversal 字符串的简单处理

    Word Reversal Time Limit: 2 Seconds      Memory Limit:65536 KB For each list of words, output a line ...

  4. 扩展jquery.validate自定义验证,自定义提示,本地化

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  5. ASP.NET/MVC 配置log4net启用写错误日志功能

    <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访 ...

  6. JavaScript设计模式--桥梁模式--XHR连接队列

    针对该模式的例子现在不是很理解,写下来慢慢熟悉. 们要构建一个队列,队列里存放了很多ajax请求,使用队列(queue)主要是因为要确保先加入的请求先被处理.任何时候,我们可以暂停请求.删除请求.重试 ...

  7. JAVA常用API(Date、DateFormat、Calendar、System、Math、基本数据类型包装类)

    注:本文所有内容均属个人见解,如有错误望各位大佬好心指点批评,不胜感激 本章重点单词: parse:解析 format:格式化 pattern:模式 amount:数量 filed :领域 1.Dat ...

  8. MAVEN 打包JAR

    <build> <finalName>edu-service-user</finalName> <resources> <resource> ...

  9. 局部刷新Ajax

    1.1.1  Ajax的由来: 如下注册界面 界面在注册的时候,需要用户输入的信息有很多,假如我们将所有的数据都录入后,在点击会员注册按钮,然后将整个页面数据进行提交,此时如果该用户名已经被占用,那么 ...

  10. sublime text3 开发必备插件

    1,Package Control 通俗易懂地说,这个是你在完成安装SublimeText后必须安装的东西.你问为什么?因为有了这个特殊的"插件包",你可以很容易地安装.升级.删除 ...