学习笔记(11月03日)

author author     2022-09-27     485

关键词:

三周五次课(11月3日)


1.生成式和生成器

1.1列表生成式python受欢迎的语法之一,通过一句简洁的语法就可以对一组元素进行过滤,还可以对得到的元素进行转换处理。

语法格式为:

[exp for val in collection if condition]

相当于

result = []
for val in collection:
    if (condition):
        result.append(exp)

例子:

a = [x * x for x in xrange(10) if x * x % 2 == 0]
print(type(a))
print(a)

结果:

<type ‘list‘>
[0, 4, 16, 36, 64]

解释:

1,以此取出xrange(10)从0到9的数字

2,判断x*x是偶数,就保留,存在新的字典中

3,把所有符合x*x是偶数的元素都放到新的列表中返回


    通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。


    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。


    生成器是一次生成一个值的特殊类型函数。可以将其视为可恢复函数。调用该函数将返回一个可用于生成连续 x 值的生成器【Generator】,简单的说就是在函数的执行过程中,yield语句会把你需要的值返回给调用生成器的地方,然后退出函数,下一次调用生成器函数的时候又从上次中断的地方开始执行,而生成器内的所有变量参数都会被保存下来供下一次使用。

    要创建一个generator,有很多种方法。第一种方法是把一个列表生成式的[]改成(),就创建了一个generator:

例子:


a = (x * x for x in xrange(10) if x * x % 2 == 0)
print(type(a))
print(a.next())
print(a.next())
print(‘aaaaaaa‘)
for i in a:
    print(i)

结果:

<type ‘generator‘>
0
4
aaaaaaa
16
36
64


解释:

generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素为止


    1.2 定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

在了解这个方法之前,我们先来看一个小例子,更好的帮助你理解yield的使用

def fib(n):
    sum = 0
    i = 0
    while (i < n):
        sum = sum + i
        i += 1
        print(sum)


fib(10)

结果:


0
1
3
6
10
15
21
28
36
45


解释:

这个程序很简单,就是求0到9所有数字之和,接下来,我们只要稍微改动一下,你看看有什么差别

def fib(n):
    sum = 0
    i = 0
    while (i < n):
        sum = sum + i
        i += 1
        yield sum


for x in fib(10):
    print(x)
print(type(fib(10)))

结果:

0
1
3
6
10
15
21
28
36
45
<type ‘generator‘>

    结果和上面的结果是一样的,但是有什么不同呢,简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。每当遇到yield关键字的时候,你可以理解成函数的return语句,yield后面的值,就是返回的值。但是不像一般的函数在return后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效,下次从yield下面的部分开始执行。

解释:

1,因为以上函数有关键字yield,所以生成的是一个生成器。

2,通过for循环调用生成器,当执行到yield的时候,返回sum的值,sum为0,此时暂停并记录sum的值

3,打印sum的值,然后继续往下执行。此时跳入下一个循环while(1<10)

4,直到遇到yield的时候,返回sum的值。

5,反复执行3,4步骤,直到循环结束,最终程序退出


二者的区别很明显:

一个直接返回了表达式的结果列表, 而另一个是一个对象,该对象包含了对表达式结果的计算引用, 通过循环可以直接输出

生成器不会一次性列出所有的数据,当你用到的时候,再列出来,更加节约内存的使用率。



2.迭代器

Iterable(可迭代对象)Iterator(迭代器)主要区别是

凡是可以用for 循环的都是Iterable(可迭代对象),凡是需要通过next()函数获得值的可迭代对象都是 Iterator(迭代器)。

  所以生成器可以next()函数调用并不断返回下一个值的对象称为迭代器(可以简单理解为生成器就是迭代器的可迭代对象)

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;


3.装饰器

    装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

简单装饰器


def use_logging(func):
    def wrapper(*args, **kwargs):
        logging.warn("%s is running" % func.__name__)
        return func(*args, **kwargs)

    retrun
    wrapper

def bar():
    print(‘i am bar‘)

bar = use_logging(bar)
bar()

    函数use_logging就是装饰器,它把执行真正业务方法的func包裹在函数里面,看起来像bar被use_logging装饰了。在这个例子中,函数进入和退出时 ,被称为一个横切面(Aspect),这种编程方式被称为面向切面的编程(Aspect-Oriented Programming)。


@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作

def use_logging(func):
    def wrapper(*args, **kwargs):
        logging.warn("%s is running" % func.__name__)
        return func(*args)
    retrun
    wrapper

@use_logging
def foo():
    print("i am foo")
    
@use_logging
def bar():
    print("i am bar")

bar()


    如上所示,这样我们就可以省去bar = use_logging(bar)这一句了,直接调用bar()即可得到想要的结果。如果我们有其他的类似函数,我们可以继续调用装饰器来修饰函数,而不用重复修改函数或者增加新的封装。这样,我们就提高了程序的可重复利用性,并增加了程序的可读性。

      装饰器在Python使用如此方便都要归因于Python的函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内。


练习题:用函数实现9*9乘法口诀

for i in range(1, 10):
    for j in range(1, i + 1):
        print j, ‘*‘, i, ‘=‘, i * j, ‘ ‘,
    print("")

结果:

1 * 1 = 1   
1 * 2 = 2   2 * 2 = 4   
1 * 3 = 3   2 * 3 = 6   3 * 3 = 9   
1 * 4 = 4   2 * 4 = 8   3 * 4 = 12   4 * 4 = 16   
1 * 5 = 5   2 * 5 = 10   3 * 5 = 15   4 * 5 = 20   5 * 5 = 25   
1 * 6 = 6   2 * 6 = 12   3 * 6 = 18   4 * 6 = 24   5 * 6 = 30   6 * 6 = 36   
1 * 7 = 7   2 * 7 = 14   3 * 7 = 21   4 * 7 = 28   5 * 7 = 35   6 * 7 = 42   7 * 7 = 49   
1 * 8 = 8   2 * 8 = 16   3 * 8 = 24   4 * 8 = 32   5 * 8 = 40   6 * 8 = 48   7 * 8 = 56   8 * 8 = 64   
1 * 9 = 9   2 * 9 = 18   3 * 9 = 27   4 * 9 = 36   5 * 9 = 45   6 * 9 = 54   7 * 9 = 63   8 * 9 = 72   9 * 9 = 81


学习笔记(11月14日)--正则

五周二次课(11月14日)11.1常用正则表达式650)this.width=650;"src="https://images.cnblogs.com/cnblogs_com/huxi/Windows-Live-Writer/Python_10A67/pyre_ebb9ce1c-e5e8-4219-a8ae-7ee620d5f9f1.png"alt="pyre"/>11.2re正则对象和正则匹配效 查看详情

11月15日jquery学习笔记

1、属性jQuery对象是类数组,拥有length属性和介于0~length-1之间的数值属性,可以用toArray()方法将jQuery对象转化为真实数组。selector属性是创建jQuery对象时的选择器字符串。context是上下文对象,是传递给$()方法的第二参数,如果没... 查看详情

11月2日——jquery源码学习笔记

1、jQuery()函数,即$()。有四种不同的调用方式。(1)传递CSS选择器(字符串)给$()方法,返回当前文档中匹配该选择器的元素集。可选第二个参数,一个元素或jQuery对象,定义元素查询的起始点,称为上下文(context),这时返... 查看详情

学习笔记之工厂模式-2017年1月11日23:00:53

  当做日记流水来写吧。今天看的工厂模式和抽象工厂。设计原则:依赖倒置原则:不依赖具体类,依赖抽象。工厂方法模式:定义了一个创建对象的接口,但由子类来决定要实例化的类是哪一个。工厂方法让类吧实例化推迟... 查看详情

html学习笔记

第一部分html发展历史1995年11月24日HTML2.0作为IETFRFC1866发布1997年1月14日HTML3.2作为W3C推荐标准发布。这是首个完全由W3C开发并标准化的版本,因IETF于1996年9月12日关闭了它的HTML工作组。1997年12月18日HTML4.0作为W3C推荐标准发布2000年5... 查看详情

学习笔记(10月16日)

一周一次课(10月16日) 1、windows下安装Python官网https://www.python.org/downloads/下载Python,版本号2.7.14,双击安装程序,一直下一步下一步直到完成,安装完成后需要在windows的环境变量path中加入python.exe的路径 2、linux下安装Pyt... 查看详情

本学期阅读计划

...书是软件需求过程,我打算每周精读一章,发表一篇阅读笔记,以下为具体发布阅读笔记时间    内容时间阅读笔记一10月12日阅读笔记二10月19日阅读笔记三10月26日阅读笔记四11月2日阅读笔记五11月9日阅读笔记六11... 查看详情

学习笔记(10月17日)--pycharm安装

一周二次课(10月17日)1.安装pycharm官网https://www.jetbrains.com/pycharm/download下载软件包,选择Community免费版本,安装比较简单,就一直下一步下一步直到安装完成。2.学会设置pycharm3.学会在pycharm中运行python程序 查看详情

2016年3月17日学习笔记----ajax(网络协议)

functionbtnClick(){varxmlhttp=newActiveXObject("Microsoft.XMLHTTP");//创建XMLHTTP对象,相当于WebClientif(!xmlhttp){alert("创建xmlhttp对象异常!");returnfalse;}xmlhttp.open("POST","GetDatel.ashx?id="+encodeURI("中国")+ 查看详情

学习笔记(10月26日)--复习&练习

二周四次课(10月26日)复习,做如下练习题1.实现1-100的所有的和sum = 0for n in xrange(1, 101):    sum += n    n += 1print(‘1+2+3+...+100& 查看详情

4月1日学习笔记(css部分)

CSS初始化内边距paddingpadding属性宽度是按照上右下左的顺序来的,否则单独设置就是padding-left。。。边框borderborder可以设置样式(border-style),颜色(border-color),宽度(border-width)。颜色和宽度都可以单独设置border-left-color/bord... 查看详情

3月31日学习笔记(html部分)

HTML标签和元素概念区别<p>是标签,<p>内容</p>是HTML元素。<pre></pre>定义预格式化文本,多用来显示源代码。表格 <map>和<area>设置图片映射<imgsrc="planets.jpg"border="0"usemap="#planetmap"alt="Planets" 查看详情

5月11日上午学习日志

2017年5月11日上午把昨天记忆的英语单词的多种词意用自己组句的方法联系起来再记忆一遍,然后再联系真题学10个考研高频词汇,然后再复习昨天的词汇,再完成英语app的打卡。 查看详情

4月11日下午学习日志

 2017年4月11日下午复习了高等数学,看完了张宇高等数学基础班课程视频第三讲考研数学视频,继续做相应的单元测试题,第二遍听课过程中能巩固之前所学内容,加深印象,对复习有很大的帮助,完成英语单词的背诵。 查看详情

学习笔记(10月18日)--pycharm基本使用方法

一周三次课(10月18日)1.     学会通过pycharm给python程序传递参数设置python的传递参数:【Run】->【EditConfigurations】->【Scriptparameters】->按顺序写上需要的参数2.     Pycharm常用快捷键总结... 查看详情

5月11日上课笔记-js简介

一、js1、javascript简介:是一门脚本语言(弱类型编程语言)(php是脚本语言)编程语言如java,先编译后运行脚本语言不需要编译作用:表单验证页面特效语法:和Java类似,但是和Java没有关系组成部分:ECMAScript(语法核心)*DOM(htmlxml,... 查看详情

12月11日学习

字典的增删改查dic=[‘name‘:‘alex‘]#增:dic[‘age‘]=21dic.setdefault()#删:pop()#尽量使用此方法cleardeldic[‘name‘]popitem()#改:updata#查:dic.keys()dic.values()dic.items() 分开获取键值的方法fork,vindic.items()  print(k,v)获取建并防止报 查看详情

2016年3月29日java学习笔记

...很尽兴。只可惜浪费了一晚上的时间。2、昨天白天开始学习异常,之前浅薄学习Python时有接触过异常,大概对异常有个了解,相比于之前写单片机的C语言来说,这些高级语言的异常处理显得既高级又很人性化,当然了,代价就... 查看详情