参考 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. requests页面请求返回400:{"errors":{"username":"值必须是非空字符串。"}}

    我的描述:我引入requests包,携带json类型数据请求(POST)一个网站,,访问提示<Response [400]> 解决方案: 1.首先使用postman请求一模一样的数据,发现 ...

  2. 后端程序员之路 29、Thrift

    Apache Thrift是Facebook实现的一个高效的.支持多种编程语言的远程服务调用(RPC)框架. Apache Thrift - Homehttp://thrift.apache.org/ ...

  3. 大话Spark(7)-源码之Master主备切换

    Master作为Spark Standalone模式中的核心,如果Master出现异常,则整个集群的运行情况和资源都无法进行管理,整个集群将处于无法工作的状态. Spark在设计的时候考虑到了这种情况 ...

  4. 微信小程序左滑删除

    <view class="touch-item {{item.isTouchMove ? 'touch-move-active' : ''}}" data-index=&qu ...

  5. PAT-1153(Decode Registration Card of PAT)+unordered_map的使用+vector的使用+sort条件排序的使用

    Decode Registration Card of PAT PAT-1153 这里需要注意题目的规模,并不需要一开始就存储好所有的满足题意的信息 这里必须使用unordered_map否则会超时 ...

  6. CCF(除法):线段树区间修改(50分)+线段树点修改(100分)+线段树(100分)

    除法 201709-5 这道题有很多种方法来做,最常用的就是线段树和树状数组. 如果使用线段树来做,就会想到区间修改的update函数.但是这里可能会涉及到v是1或者a[j]是0的情况,所以用这种方法 ...

  7. JVM-对象及对象内存布局

    目录 前言 类与对象 对象类二分模型 对象 对象内存布局 JOL工具 对象头 Mark Word 类型句柄 对象头与锁膨胀 无锁 偏向锁 轻量级锁 重量级锁 重量级锁降级 实例数据 填充 对象生命周期 ...

  8. Java 常见对象 05

    常见对象·正则表达式 和 其他类 正则表达式的概述和简单使用 * A:正则表达式 * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则,有自己的特殊应用 * 作用: ...

  9. JVM实战调优(空格引发的服务异常)

    JVM实战调优 问题描述 某一个项目中有一个文字转语音的服务,使用的是科大讯飞的语音转换服务,需要调用三方服务.因其转换服务是一个耗时操作,官方给的demo使用的是 WebSocket 进行数据转换操 ...

  10. (2)MySQL进阶篇SQL优化(show status、explain分析)

    1.概述 在应用系统开发过程中,由于初期数据量小,开发人员写SQL语句时更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,很多SQL语句开始逐渐显露出性能问题,对生产环境的影响也 ...