参考 Python学习手册 第四版

1 from vs import

  • import 模块 : 导入的一整个模块(python中模块对应一个py文件)

    因为import使用一个变量名引用整个模块对象,所以必须通过模块名称来得到该模块的属性。

    程序在第一次导入指定模块的时候,会执行三个步骤

    1. 找到模块文件
    2. 编译成字节码(需要时)
    3. 执行模块的代码来创建其所定义的对象

    这三个步骤,只在模块第一次被导入时才进行,第二次导入则不会,只会提取内存中已加载的模块对象。

    从技术上讲,python将载入的模块存储到一个名为``sys.modules`的表中,并在一次导入操作的开始检查该表,如果模块不存在,将会启动这三个步骤。

  • from... import : 导入模块中的一个变量

    因为from会把变量名复制到另一个作用域,所以就可以直接在脚本中使用复制后的变量名,而不需要通过模块访问

举个粒子

先建立一个ttttest.py脚本文件,输入一行代码。

cnblog_name = "XiiX"

使用import需要通过模块名称来访问,导入的是一个模块

In [6]: import ttttest

In [7]: ttttest.cnblog_name
Out[7]: 'XiiX' In [8]: type(ttttest)
Out[8]: module

使用from可以直接访问,可以看到导入的就是一个变量

In [10]: from ttttest import cnblog_name

In [11]: cnblog_name
Out[11]: 'XiiX' In [12]: type(cnblog_name)
Out[12]: str

import和from其实是一个赋值语句

请注意,它们不是编译期间的声明,而是一个可以执行的语句。

  • import 将整个模块对象赋值给一个变量名
  • form 将一个或多个变量名赋值给另一个模块中同名的对象

2 列表解析

在处理序列的操作和列表的方法中,python有一个更高级的操作——列表解析表达式(list comprehension expression)。列表解析常常具有处理速度上的优势(会比手动的for循环语句快一倍以上,因为它们的迭代在解释器内存是以C语言的速度执行的而不是以手动python代码执行),能够在python的任何序列类型中发挥作用,甚至一些不属于序列的类型。

虽然列表解析速度上很有优势,但是只适用于小规模的任务,对于大规模的数值运算,使用Numpy包的效率会更高。

举个粒子:

  • 假设我们需要从矩阵中提取出第二列,我们可以通过一行代码就能解决这个问题

    In [2]: M
    Out[2]: [[1, 2, 4], [2, 5, 6], [1, 2, 3]] In [3]: col2 = [row[1] for row in M] In [4]: col2
    Out[4]: [2, 5, 2]

列表解析源自集合的概念,是一种通过对序列中的每一项运行一个表达式来创建一个新列表的方法。列表解析是编写在方括号中的(提醒你在创建一个新列表),并且使用了同一个变量名(这里是row)的表达式和循环结构组成。

实际操作中,我们还可以加一些额外的操作,比如算术运算,过滤等操作

# +1
In [5]: [row[1] +1 for row in M]
Out[5]: [3, 6, 3] # 只取出偶数
In [6]: [row[1] for row in M if row[1]%2==0 ]
Out[6]: [2, 2]

再举一些粒子,大家也可以发挥自己的想象力

  • 取出矩阵中的对角线上的值,非常的方便

    In [8]: [M[i][i] for i in range(len(M))]
    Out[8]: [1, 5, 3]
  • 分离字符串,不过list()也能做

    In [9]: [c+',' for c in "Hello"]
    Out[9]: ['H,', 'e,', 'l,', 'l,', 'o,'] In [10]: list('Hello')
    Out[10]: ['H', 'e', 'l', 'l', 'o']

还可以使用嵌套的循环

In [13]: [x+y for x in "abc" for y in "XiiX"]
Out[13]: ['aX', 'ai', 'ai', 'aX', 'bX', 'bi', 'bi', 'bX', 'cX', 'ci', 'ci', 'cX']

3 range迭代器

python3.0中,range返回一个迭代器,该迭代器根据需要产生范围内的数字,而不是在内存中构建一个结果列表。会比较节省空间。

如果需要一个列表的话,可以使用list(range(...))强制产生一个真正的范围列表

In [15]: r = range(0,10)

In [16]: r
Out[16]: range(0, 10) In [17]: list(r)
Out[17]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

python3.0中,range对象只支持迭代、索引以及len函数,不支持其他的序列操作。

In [18]: len(r)
Out[18]: 10 In [19]: r[0]
Out[19]: 0 In [20]: r[2]
Out[20]: 2 In [22]: I = iter(r) In [23]: next(I)
Out[23]: 0 In [24]: next(I)
Out[24]: 1

4 map、zip和filter迭代器

和range类似,,map、zip以及filter内置函数在Python3.0中也转变为迭代器以节约内存空间。

但是和range不同,它们都是自己的迭代器——在遍历其结果一次之后,它们就用尽了,换句话说,不能在它们的结果上引用在那些结果中保持不同位置的多个迭代器。

In [35]: m = map(abs, (-2,-1,0))

In [36]: m
Out[36]: <map at 0x7fb371ca4130> In [37]: next(m)
Out[37]: 2 In [38]: next(m)
Out[38]: 1 In [39]: next(m)
Out[39]: 0 In [40]: next(m)
StopIteration

可以看到,在遍历一次之后,它们就用尽了。无法再继续遍历。

如果还是不明白的话,我们再来观察一下对zip的试验。可以看到两次迭代之后,用list强制转换z,之后只剩一个值, 所以值是在消耗的,一旦迭代一次过后,这个值就没有了。

注意:list(z)会一次性将其全部消耗

In [49]: z = zip((1,2,3),(10,20,30))

In [50]: next(z)
Out[50]: (1, 10) In [51]: next(z)
Out[51]: (2, 20) In [52]: list(z)
Out[52]: [(3, 30)] In [53]: next(z)
StopIteration:

多个迭代器vs单个迭代器

range可以同时存在多个迭代器,并且支持len和索引,但是不是自身的迭代器,是使用iter产生的迭代器。

可以看到range本身没有迭代器,要使用iter产生,产生的迭代器之间互不干扰是独立的。

In [54]: r = range(3)

In [55]: next(r)
TypeError: 'range' object is not an iterator In [56]: I1 = iter(r) In [57]: I2 = iter(r) In [58]: next(I1)
Out[58]: 0 In [59]: next(I2)
Out[59]: 0

相反,zip和map和filter之间不支持相同结果上的多个迭代器同时存在。

从下方试验的代码可以看到,即使定义了两个迭代器,但是由于迭代是不断消耗的(与range不同),所以两个迭代器实际上指向的位置是一致的。

In [60]: z = zip((1,2,3),(1,2,3))

In [61]: I1 = iter(z)

In [62]: I2 = iter(z)

In [63]: next(I1)
Out[63]: (1, 1) In [64]: next(I1)
Out[64]: (2, 2) In [65]: next(I2)
Out[65]: (3, 3) In [66]: next(I2)
StopIteration: In [67]: next(I1)
StopIteration:

map

在程序中对列表和其他序列常常要做的一件事就说对每一个元素进行一个操作,并把其结果集合起来,这样的情况就可以使用map来进行操作。

例如,在一个列表counter中更新所有的数字,这虽然可以写一个for循环,完成,但是通过map会更加高效。

lambda的使用见下一节

In [5]: counter = [1,2,3,4]

## for
In [6]: temp = [] In [7]: for x in counter:
...: temp.append(x + 10)
...: In [8]: temp
Out[8]: [11, 12, 13, 14] ## map
In [9]: list(map(lambda x:x+10, counter))
Out[9]: [11, 12, 13, 14]

zip

使用zip可以配对来自多个序列的参数

In [12]: list(zip((1,2,3),(4,5,6),(7,8,9)))
Out[12]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

filter

函数式编程工具filter,在python的内置函数中,map函数是用来进行函数式编程的这类工具中最简单的内置函数代表。

函数式编程的意思就是对序列应用一些函数的工具,例如,基于某一测试函数过滤出一些元素(filter)

举个例子,从一个序列中挑选出大于0的元素

In [11]: list(filter( (lambda x: x>0), range(-5,3) ))
Out[11]: [1, 2]

5 lambda表达式

lambda名称是来自LISP,而LISP则是从lambda calculus (一种符号逻辑形式)取得到的名称。

除了def以外,python还提供了一种生成函数对象的表达式形式,lambda。就像def一样,这个表达式创建了一个能够调用的函数,但是它返回了一个函数而不是将这个函数赋值给一个变量名。这也是lambda有时也叫做匿名函数的原因。

lambda表达式的一般写法

lambda argument1, argument1, ... argumentN : expression using arguments
  • lambda是一个表达式,而不是一个语句。因为这一点,lambda可以出现在python语法不允许def出现的地方——例如,在一个列表常量中或者函数调用的参数中。
  • lambda的主体是一个单个的表达式,而不是一个代码块。主体非常简单,也决定了其不能执行复杂的任务
In [68]: def func(x,y,z): return x+y+z

In [69]: func(1,24,1)
Out[69]: 26 In [70]: f = lambda x,y,z:x+y+z In [71]: f(2,3,4)
Out[71]: 9

这里的f被赋值给一个lambda表达式创建的函数对象,这也就是def所完成的任务。只不过def的赋值是自动进行的。

此外,默认参数也能够在lambda参数中使用

In [72]: x = (lambda a='fee', b='fie', c='foe': a+b+c)

In [73]: x("wee")
Out[73]: 'weefiefoe'

为什么要使用lambda?

总体而言,使用lambda起到了一种函数速写的作用,允许在使用的代码内嵌入一个函数的定义。虽然能用def来代替,但是使用lambda会更简洁。

lambda通常用来编写跳转表(jump table),也就是行为的列表或者字典。

In [1]: L = [lambda x : x**2, lambda x : x**3, lambda x : x**4 ]

In [2]: for f in L:
...: print(f(2))
...:
4
8
16

像这样的情况,def无法直接写入列表,只能先定义好三个def,然后再创建列表,毫无疑问,使用lambda会更为高效。

还可以写入字典里

In [3]: dict = {'already':(lambda:2+2), 'got':(lambda:2*4),'one':(lambda:2**3)}

In [4]: dict['got']()
Out[4]: 8

下一章会讲一下python的对象

Python 高级进阶知识(一)的更多相关文章

  1. Python高级进阶(一)Python框架之Django入门

    传说中的Django Django由来 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下 ...

  2. Python高级进阶(二)Python框架之Django写图书管理系统(LMS)

    正式写项目准备前的工作 Django是一个Web框架,我们使用它就是因为它能够把前后端解耦合而且能够与数据库建立ORM,这样,一个Python开发工程师只需要干自己开发的事情就可以了,而在使用之前就我 ...

  3. 一凡老师亲录视频,Python从零基础到高级进阶带你飞

    如需Q群交流 群:893694563 不定时更新2-3节视频 零基础学生请点击 Python基础入门视频 如果你刚初入测试行业 如果你刚转入到测试行业 如果你想学习Python,学习自动化,搭建自动化 ...

  4. python最全学习资料:python基础进阶+人工智能+机器学习+神经网络(包括黑马程序员2017年12月python视频(百度云链接))

    首先用数据说话,看看资料大小,达到675G 承诺:真实资料.不加密,获取资料请加QQ:122317653 包含内容:1.python基础+进阶+应用项目实战 2.神经网络算法+python应用 3.人 ...

  5. python学习大全:python基础进阶+人工智能+机器学习+神经网络

    首先用数据说话,看看资料大小,达到675G承诺:真实资料.不加密.(鉴于太多朋友加我QQ,我无法及时回复,) 方便的朋友给我点赞.评论下,谢谢!(内容较大,多次保存) [hide]链接:[url]ht ...

  6. Python高级编程和异步IO并发编程

    第1章 课程简介介绍如何配置系统的开发环境以及如何加入github私人仓库获取最新源码. 1-1 导学 试看 1-2 开发环境配置 1-3 资源获取方式第2章 python中一切皆对象本章节首先对比静 ...

  7. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  8. Spring实战3:装配bean的进阶知识

    主要内容: Environments and profiles Conditional bean declaration 处理自动装配的歧义 bean的作用域 The Spring Expressio ...

  9. MEF高级进阶

    MEF高级进阶   好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四 ...

随机推荐

  1. 别再人云亦云了!!!你真的搞懂了RDD、DF、DS的区别吗?

    几年前,包括最近,我看了各种书籍.教程.官网.但是真正能够把RDD.DataFrame.DataSet解释得清楚一点的.论据多一点少之又少,甚至有的人号称Spark专家,但在这一块根本说不清楚.还有国 ...

  2. 2021-2-22:请你说下 CAP 理论并举例

    CAP CAP 理论是分布式系统中的一个老生常谈的理论了,最早由 Eric Brewer 在一个讲座中提出.在这个讲座中,在传统 ACID 理论以及当时比较流行但是比较抽象的的设计指导理论 BASE ...

  3. 解决margin-top无效问题

    当两个空的块级元素嵌套时,如果内部的块设置有margin-top属性,而且父元素没有下边解决方法所述的特征,那么内部块的margin-top属性会绑架父元素(即将margin-top传递凌驾给了父元素 ...

  4. .NET 云原生架构师训练营(模块二 基础巩固 安全)--学习笔记

    2.8 安全 认证 VS 授权 ASP .NET Core 认证授权中间件 认证 JWT 认证 授权 认证 VS 授权 认证是一个识别用户是谁的过程 授权是一个决定用户可以干什么的过程 401 Una ...

  5. xscan的安装和使用(作业整理)

    1.将学习通上下载的xscan.rar进行解压. 2.将缺少的.dll文件粘贴到软件解压目录中. 3.点击打开软件. 3.1在运行中除了发现缺少.dll文件的问题,我电脑又出现类似问题, 采取了关闭防 ...

  6. css3自动换行排列

    如果一行放不下就会自动换行 display: flex; flex-wrap: wrap; 示例 : html <div class="container"> < ...

  7. 后端程序员之路 31、Protocol Buffer

    google/protobuf: Protocol Buffers - Google's data interchange formathttps://github.com/google/protob ...

  8. Hi3559板载u-boot、kernel及rootfs烧录过程及心得

    这一篇随笔讲叙述下基于Hi3559AV100的BOXER-8410AI板载u-boot.kernel及rootfs烧录具体过程及遇到问题的解决方法与心得. 1.前期板载启动测试和烧录手段 1.1.烧写 ...

  9. 模式识别Pattern Recognition

    双目摄像头,单目摄像头缺少深度 Train->test->train->test->predicive

  10. MySQL深入研究--学习总结(3)

    前言 接上文,继续学习后续章节.细心的同学已经发现,我整理的并不一定是作者讲的内容,更多是结合自己的理解,加以阐述,所以建议结合原文一起理解. 第九章<普通索引和唯一索引,如何选择> 从查 ...