今日主要内容

  • 补充:三目运算
  • f-strings
  • 迭代器
  • 生成器

补充:三目运算

  1. 三目运算(三元运算)结构:
  • 表达式1 if 条件表达式 else 表达式2
  • c = a if a > b else b
  1. 执行流程:

    • 判断条件,如果条件正确将a赋值给c
    • 如果条件不正确将b赋值给c
    a = 10
    b = 20
    c = a if a > b else b # 三目运算
    print(c) 运行结果:
    20

一、f-strings

  • f-strings之前我们已经说过了,python3.6以上的版本可以使用,用来格式化输出,非常的方便,今天来详细说一下
  1. f-strings的格式:

    • f"xxxx{传入的变量}xxxx"(建议使用f
    • F"xxxx{传入的变量}xxxx"(不建议使用F
    name = "zxd"
    age = 23
    print(f"姓名:{name} 年龄:{age}") 运行结果:
    姓名:zxd 年龄:23
  2. 引号中如果需要大括号{}时,用两个{{}}代表

    print(f"{{'a'}}")  # 用两个大括号表示
    
    运行结果:
    {'a'}
  3. 引号中需要使用引号时,一定用两个单引号''表示

    print(f"{{'a'}}")  # 用单引号表示
    
    运行结果:
    {'a'}
  4. 传入的参数可以是三目表达式

    a = 10
    b = 10
    print(f"{a if a > b else b}") 运行结果:
    10

二、迭代器

(一)可迭代对象

  • 说迭代器之前咱们来看一看可迭代对象,什么是可迭代对象?

    • 可以一个一个取值的对象就是可迭代对象
    s = "12345"
    lst = [1, 2, 3, 4, 5]
    dic = {1: 1, 2: 2, 3: 3}
    ....... # 这些都是可迭代对象
    • 他们共有的一个特点就是可以被for循环
    s = "12345"
    lst = [1, 2, 3, 4, 5]
    dic = {1: 1, 2: 2, 3: 3} for el in s:
    print(el)
    for el in lst:
    print(el)
    for el in dic:
    print(el)
  1. 查看可迭代对象的官方方法:

    • 查看对象是否有__iter__()方法,只要使用有此方法的对象全部都是可迭代对象
    • dir()函数可以查看对象所有的方法
    lst = [1, 2, 3, 4, 5]
    print("__iter__" in dir(lst)) 运行结果:
    True
  2. 可迭代对象的特点:

    • 空间换时间的理念(用大量的空间节省时间)
    • 优点:
      • 使用灵活,每个可迭代对象都有自己的方法
      • 能够直接查看元素个数
      • 可以重复取值
    • 缺点:
      • 占内存
  3. 应用:内存空间大,当数据量比较少,建议使用可迭代对象

(二)迭代器

  • 迭代器可以理解成可迭代对象的实体化,它只继承了迭代性(可以一个一个取值),同时节约了内存(唯一的优点)
  • 文件句柄就是一个迭代器
  1. 迭代器的生成方法:

    • 两种生成方法效果相同
    • iter(可迭代对象)
      • 生成可迭代对象的迭代器
      • 打印的是迭代器的地址
    lst = [1, 2, 3, 4, 5]
    l = iter(lst)
    print(l) 运行结果:
    <list_iterator object at 0x0000020BAFCEA940>
    • 可迭代对象.__iter__()

      • 生成可迭代对象的迭代器
      • 打印的是迭代器的地址
    lst = [1, 2, 3, 4, 5]
    l = lst.__iter__()
    print(l) 运行结果:
    <list_iterator object at 0x000002490EFDA8D0>
  2. 迭代器的取值

    • 迭代器最大的特点就是惰性机制,如果不主动向迭代器取值,迭代器是不会给你值的,同时也正因为惰性机制节约了内存
    • next(迭代器)
    lst = [1, 2, 3, 4, 5]
    l = iter(lst)
    print(next(l))
    print(next(l))
    print(next(l))
    print(next(l))
    print(next(l)) 运行结果:
    1 2 3 4 5
    • 迭代器.__next__()
    lst = [1, 2, 3, 4, 5]
    l = lst.__iter__()
    print(l.__next__())
    print(l.__next__())
    print(l.__next__())
    print(l.__next__())
    print(l.__next__()) 运行结果:
    1 2 3 4 5
    • 每次执行取值函数只向迭代器取一个值,按顺序向下取值,不能重复取值,迭代器中有多少个元素就只能next多少次,超出最大个数会报错
    lst = [1, 2, 3, 4, 5]
    l = lst.__iter__()
    print(l.__next__())
    print(l.__next__())
    print(l.__next__())
    print(l.__next__())
    print(l.__next__())
    print(l.__next__()) 运行结果:
    1 2 3 4 5
    StopIteration
  3. 迭代器的特点:

    • 时间换空间理念(用大量的时间去节省空间)
    • 节省内存
    • 惰性机制
    • 只能向下取值,不能往复
  4. for循环的本质就是一个迭代器

    • 捕获异常:向迭代器取值超出迭代器元素数量时,会捕获StopIteration异常,从而终止while循环
    lst = [1, 2, 3, 4, 5]
    l = iter(lst)
    while True:
    try:
    print(next(l))
    except StopIteration: # 捕获异常
    break
  5. 向同一个迭代器取值,迭代器内部会记录取值位置,赋值给变量,变量会指向地址和上次取值位置

    lst = [1, 2, 3, 4, 5]
    l_iter = iter(lst)
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter)) # l_iter指向取值记录位置 运行结果:
    1 2 3 4 5
    • l_iter指向迭代器的地址,每一次取值,l_iter指向上一次取值位置
    • 可以理解成通过熟人买东西,每次买都是上次的优惠价
  6. 向同一个迭代器取值,迭代器内部会记录取值位置,若不赋值,每一次取值都从开头取值,相当于每次寻址后都从头开始

    lst = [1, 2, 3, 4, 5]
    print(next(iter(lst)))
    print(next(iter(lst)))
    print(next(iter(lst)))
    print(next(iter(lst)))
    print(next(iter(lst)))
    print(next(iter(lst))) # 每次都从头开始取值 运行结果:
    1 1 1 1 1
    • 没有赋值每次通过func()直接寻址,都从头部开始取值
    • 可以理解成没有熟人了,每次买东西都是原价
  7. 应用:内存小,数据量巨大时,建议使用迭代器

(三)两者关系

  • 迭代器一定是可迭代对象,可迭代对象不一定是迭代器
  • 迭代器可以通过iter(可迭代对象)可迭代对象.__iter__()得到

三、生成器

(一)什么是生成器

  • 生成器的本质就是迭代器

  • 生成器就是一个自己写的迭代器,而迭代器只能通过iter()函数得到

  • 生成器的目的是不通过数据转换实现,通过代码实现

    • 列表转换成了迭代器,但是列表依旧加载到了内存,没有达到省内存的效果
    lst = [1, 2, 3, 4, 5]
    l_iter = iter(lst)
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter)) 运行结果:
    1 2 3 4 5
    • 通过生成器真正达到省内存的效果
    def func():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5 f_gen = func()
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen)) 运行结果:
    1 2 3 4 5

(二)生成器

  1. 通过函数实现生成器

    • 先来看一个函数
    def func():
    print(1)
    return 1 print(func()) 运行结果:
    1 1
    • 将函数中return替换成yield就变成了一个生成器
    def func():
    print(1)
    yield 1 print(func()) 运行结果:
    <generator object func at 0x000001B27042C50>
    • 如果定义的是函数,函数名加括号是调用函数;而如果定义的是生成器,函数名加括号是得到的是生成器的内存地址
    • yield
      • yield能返回多个值,以元组形式存储
      • yield能返回各种数据类型
      • yield能够写多个并且都能执行
      • yield能够记录执行位置
      • yield后面不写内容,默认返回None
      • yield只能向下进行,不能往复,一次性取值
  2. 生成器的取值

    • next(生成器)
    def func():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5 f_gen = func()
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen)) 运行结果:
    1 2 3 4 5
    • 生成器.__next__()
    def func():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5 print(func().__next__())
    print(func().__next__())
    print(func().__next__())
    print(func().__next__())
    print(func().__next__()) 运行结果:
    1 2 3 4 5
  3. 生成器的本质就是一个迭代器,所以它拥有迭代器的所有特点

    • 时间换空间理念(用大量的时间去节省空间)
    • 节省内存
    • 惰性机制
    • 只能向下取值,不能往复
  4. 向同一个生成器取值,yield会记录取值位置,赋值给变量,变量会指向地址和上次取值位置

    def func():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5 f_gen = func()
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen))
    print(next(f_gen)) # f_gen指向生成器地址和yiele记录的位置 运行结果:
    1 2 3 4 5
  5. 向同一个生成器取值,yield会记录取值位置,若不赋值,每一次取值都从开头取值,相当于每次寻址后都从头开始

    def func():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5 print(next(func()))
    print(next(func()))
    print(next(func()))
    print(next(func()))
    print(next(func())) # 每次都从头开始取值 运行结果:
    1 2 3 4 5
  6. 若yield的值是个可迭代对象,还可以将其对象逐个返回

    • yield from
    def func():
    yield from [1, 2, 3]
    yield from [4, 5, 6] print(next(func()))
    print(next(func()))
    print(next(func()))
    print(next(func()))
    print(next(func()))
    print(next(func())) 运行结果:
    1 2 3 4 5 6

四、三者区分

(一)可迭代对象

  • 只要是可以使用__iter__()方法的对象都是可迭代对象
  • 迭代器和生成器都是可迭代对象

(二)迭代器

  • 查看对象的内存地址,如果有iterator就是一个迭代器
  • 拥有__iter__()__next__()放法的就是一个迭代器

(三)生成器

  • 查看对象的内存地址,如果有generator就是一个生成器
  • 可以使用send()方法的就是一个生成器

Python基础(十一)的更多相关文章

  1. Python基础(十一) 类继承

    类继承: 继承的想法在于,充份利用已有类的功能,在其基础上来扩展来定义新的类. Parent Class(父类) 与 Child Class(子类): 被继承的类称为父类,继承的类称为子类,一个父类, ...

  2. python 基础(十一) pickle 序列化

    一.pickle序列化的操作 使用说明:可以将数据 转换成2进制 写入到文件中 或者之间返回 做到将数据原样写入 原样取出 import pickle (1) dump 写入文件中 pickle.du ...

  3. python基础十一之迭代器和生成器

    可迭代 内置方法中含有__iter__的数据类型都是可迭代的,只要是可迭代的就可以使用for循环,反之亦然. print(dir('')) # dir()函数可以获取当前数据类型的所有内置方法 返回值 ...

  4. python基础十一之装饰器进阶

    函数的双下划线方法 def hahahha(): """测试函数""" print('zxc') print(hahahha.__name_ ...

  5. 二十一. Python基础(21)--Python基础(21)

    二十一. Python基础(21)--Python基础(21) 1 ● 类的命名空间 #对于类的静态属性:     #类.属性: 调用的就是类中的属性     #对象.属性: 先从自己的内存空间里找名 ...

  6. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  7. Python基础学习笔记(十一)函数、模块与包

    参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-functions.html 3. http://www.liao ...

  8. Python基础笔记系列十一:标准输入输出、文件读写和指针等操作

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 标准输入输出一.输入 在sublime中这个时候需要安装SublimeRE ...

  9. Python 基础语法(四)

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

  10. Python基础教程【读书笔记】 - 2016/8/3

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第十一波:第11章  文件和素材 本章更进一步,让程序能够接触更多的领域:文件和流.接下来介绍的函数和对象可以让你在程序 ...

随机推荐

  1. SSH原理讲解与实践

    一.简介 SSH全名Secure Socket Shell,安全外壳传输协议.专为远程登录会话和其他网络服务提供安全性的协议 二.加密算法 要了解SSH的原理,就要先知道目前主流的俩种加密算法 2.1 ...

  2. Hbase多版本(version)数据写入和读取

    1. 首先创建一个支持多版本的hbase表 create }   2.put几条测试数据 put ','f1:name','jack1' put ','f1:name','jack2' 3.读取多版本 ...

  3. 小白学Python(2)——常用Python编程工具,Python IDE

    下载好Python,但是如何开始编程呢? 有几种方法, 1.第一个就是command lind 即为命令行的方式,也就是我们常说的cmd. 输入 win+ cmd 在命令行中再输入 python,即可 ...

  4. SSH开发模式——Struts2(第一小节)

    在制定了学习计划的学习过程中,我感觉学习还是很有效率的.很短的时间内,我便学习完了JavaWeb的连接池.DbUtils框架及其一些工具类的使用. 学无止境,学习这些知识还远远不够,所以,在接下来的时 ...

  5. HTML5 storage事件监听

    引用<h5移动web开发指南>上的话: “当同源页面的某个页面修改了localStorage,其余的同源页面只要注册了storage事件,就会触发” 所以,localStorage  st ...

  6. xgboost保险赔偿预测

    XGBoost解决xgboost保险赔偿预测 import xgboost as xgb import pandas as pd import numpy as np import pickle im ...

  7. [C#] 改进SqliteHelper, 减少拼接SQL语句

    说明:开始几个是基本的方法,后面稍微封装了下 public class SqliteHelper { //连接字符串 private static readonly string str = Conf ...

  8. ES5新增数组的一些方法

    1.Array.indexof(value1,value2) Tip:用于返回某个数组或字符串中规定字符或者字符串的位置. (1)当Array.indexof(value1);里面只有一个值的时候,表 ...

  9. NLP(六) 分块、句法分析、依存分析

    内置分块器 分块:从文本中抽取短语 import nltk text = 'Lalbagh Botanical Garden is a well known botanical garden in B ...

  10. [python]python列表、元组

    1. 列表和元组简介 列表:用中括号[]包裹,元素的个数及元素的值可以改变. 元组:用小括号()包裹,不可用更改. 通过切片运算[]和[:]可以得到子集. 2.列表 示例: List = [1, 2, ...