一)列表解析表达式
定义: 它是通过对“序列”中的每一项运行一个表达式来创建一个新的列表的方法,每次一个,从左至右,其能够在任何可迭代的对象上进行迭代。
语法: [ item for item in seq [if statement]] //可以用if语句对迭代结果进行筛选
举例:
>>>a = [1,2,3,4,5]
>>>[i for i in a if i % 2 == 0]
>>>[2, 4]
二)生成器表达式
定义: 它是通过对“序列”中的每一项运行一个表达式来创建一个新的生成器对象,每次一个,从左至右,其能够在任何可迭代的对象上进行运算。
语法: (item for item in seq [if statement]) //可以用if语句对运算结果进行筛选
举例:
>>>a = [[1,2,3],[4,5,6],[7,8,9]]
>>>(sum(i) for i in a if i[i] % 5 == 0]
>>>[15]
>>>[i for i in (sum(row) for row in a)]
>>>[6,15,24]
注:生成器是迭代器的一种,迭代器支持next(iterator)方法和iterator.__next__()方法。
三)列表解析语法扩展运用:用来创建集合和字典
定义: 它是通过对“序列”中的每一项运行一个表达式来创建一个新的集合或字典,每次一个,从左至右,其能够在任何可迭代的对象上进行运算。
举例:
>>>{ord(x) for x in 'spaam'}
>>>{112, 97, 115, 109} //集合会自动去重
>>>{x:ord(x) for x in 'spaam'}
>>>{'a':97,'p':112,'s':115,'m':109} //字典的key唯一
四)创建字典的其他方法
1.
>>>dict(name='liyu', age=31)
>>>{'name':'liyu','age':31}
2.
>>>dict(zip(keyList, valueList))
3.
>>>dict.fromkeys(sequence, defaultValue)
>>>dict.fromkeys('ab',0)
>>>{'a':0,'b':0}
五)迭代器及常见迭代工具
可迭代的:指可用迭代工具依次取出值的对象,如字符串,列表,元组等,同时可用内置函数iter()或者对象本身的__iter__()方法将该对象转换成迭代器对象。
迭代器:指支持迭代工具的同时,还可以用内置函数next()或对象本身的__next__()方法依次取出值的对象。
总之:迭代器一定是可迭代的,但可迭代的不一定是迭代器,如常见的字符串,列表等是可迭代的,但不是迭代器。(由于迭代器一定是可迭代的,因此迭代器也支持iter()和__iter__()函数及方法,只是iter(迭代器)就是迭代器本身。)
常见迭代工具:for, in, map, zip, 列表解析,sorted, enumerate, sum, any, max, min等。map使用
语法: map(funcName, iterableObject)
>>> b = map(abs, [-1, 0, 1]) //返回map迭代器
注:map参数可以是多个序列,每个序列相应位置的值同时传给运算函数;如果序列成员个数不一致,则以最短序列为准。
zip使用
语法: zip(iterableObject, iterableObject, ...)
>>> c = zip('abc', [1,2,3], [4,5,6]) //返回zip迭代器
注:如果序列成员个数不一致,则以最短序列为准。
filter使用
用法与map类型,其返回filter迭代器(对可迭代对象的每一项进行函数运算,如果运算后结果为True,则该项作为filter迭代器中的一项)。
六)闭合函数(工厂函数)
定义:一个能够记住嵌套作用域(具有嵌套作用域的基础或者说前提是,须有嵌套的函数定义)的变量值的函数。(注:Python函数能够保存状态信息的主要方法有三种:全局变量、闭合函数及默认参数。)
举例:
def func1(y):
def func2(x)
return(x**y)
return(func2) //这里返回的是内层函数名(内层函数对象)
>>>f = func1(2) //y为2这个func1的本地变量值被保存,并将内层函数对象赋值给变量f(即重命名func2为f)。
>>>f(3)===>9
>>>f(4)===>16
七)嵌套作用域与lambda匿名函数表达式
注:为什么将lambda匿名函数称为lambda匿名函数表达式,是因为lambda会创建一个函数对象,并将该对象返回,使用者需要用一个变量来引用(“存储”)该对象,所以称为表达式。(与一般意义的def区别就在于,def创建函数对象,并会将该函数对象赋值给函数名。)
由于嵌套作用域的查找原则和工厂函数能保存记住嵌套作用域变量值的特性,lambda函数和def函数定义可自然而然地结合使用:
def func1(y):
action = (lambda x: x**y)
return(action)
>>>f=func1(2)
>>>f(3)===>9
>>>f(5)===>25
特别注意:如果lambda或者def嵌套在函数中定义,且其定义嵌套在一个循环之中并且嵌套的函数引用了一个上层作用域的变量,而该变量又被循环所改变,则所有在这个循环中产生的函数将会有相同的值——在最后一次循环中完成时被引用变量的值。
def makeActions():
acts=[]
for i in range(5):
acts.append(lambda x: i**x)
return(acts)
actions=makeActions()
>>>actions[0](2)===>16 //i始终使用的是4
>>>actions[4](2)===>16
如果想得到下面结果:
>>>actions[0](2)===>0 //i随循环递增
>>>actions[4](2)===>16
则函数需做如下修改:
def makeActions():
acts=[]
for i in range(5):
acts.append(lambda x, i=i: i**x) //原理是:如果不添加i=i,则每次调用lambda函数时都是找父函数中的i,而父函数中的i在循环完成时已经变为了4;添加了i=i,则每次创建lambda函数时,相当于在lambda函数内部创建了变量名为i的本地变量
return(acts)
八)__init__.py文件的使用
该文件主要有3大作用:包的初始化:Python首次导入某个目录或目录下的目录或文件时,系统会自动执行该目录下的__init__.py文件中的代码,因此该文件通常存放一些初始化代码及钩子函数等;
给目录虚拟化一个模块对象,从而形成目录(虚拟化目录模块)的命名空间。当使用"import 目录"直接导入目录时,系统会为目录创建一个同名虚拟模块命名空间,且该命名空间包含了目录下__init__.py文件中所有赋值的变量名(注:仅包含__init__.py文件中定义或引入的,而不会包含该目录下的子模块或目录)。
可在__init__.py文件中定义__all__列表自定义采用 “from 目录 import *”方式导入目录下变量的时候会导入哪些该目录下的子模块,如果不定义__all__列表,“from 目录 import *”所导入的变量实质是等同于"import 目录"的,区别只是在于一个可直接访问,或者需要以目录.变量访问。(注:__all__定义仅适用于from *模式导入(如果用import 目录模式导入,__all__列表设置不起作用),且一旦定义了__all__列表且用from *模式导入,则__init__.py文件自身的变量不可被导入,除非也将其写入__all__列表。)
九)_x及__all__设置隐藏模块及目录导入数据
_x是以单下划线开始的变量定义(私有变量声明),__all__是设置变量名列表,这2者均可设置在__init__.py文件和普通的模块文件,其使用范围也均仅限于from *模式导入方式。_x方式定义其不可被导入,而__all__定义其可被导入,两者作用相反。
十)