Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
百融榕树定义函数时,需要确定函数名和参数个数;如果有必要,可以先对参数的数据类型做检查;函数体内部可以用return随时返回函数结果;函数执行完毕也没有return语句时,自动return None。函数可以同时返回多个值,但其实就是一个tuple。
百融榕树默认函数参数,放在必选参数后,默认参数必须指向不变对象!
可变参数的实现是通过在调用函数时,传入参数为一个list或者tuple形式。
*nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见
关键字参数,**key, 以传入任意个数的关键字参数
Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
切片操作符 例如:>>>L[0:3]表示取L这个list中,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2
百融榕树倒数第一个元素的索引是-1
>>> L[:10]表示取前十个数0~9如果第一个索引是0,可以省略
>>>L[:10:2]表示前十个数,每两个取一个
甚至什么都不写,只写[:]就可以原样复制一个list:
tuple也可以用切片操作,只是操作的结果仍是tuple
百融榕树字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串
迭代:
如果百融榕树给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代。只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代。
百融榕树Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身。
上面的for循环里,同时引用了两个变量,在Python里是很常见的。
列表生成式是Python内置的非常简单却强大的可以用来创建list的生成式
例如创建list[1,2,3,4,5,6,7,8,9,10]
list(range(1, 11))
要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?
方式一:循环
>>>L=[]
>>>for x in list(range(1,11)):
L.append(x*x)
>>>L
方式二:
百融榕树列表生成式则可以用一行语句代替循环生成上面的list
>>> [x * x for x in range(1, 11)]
百融榕树写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来.
生成偶数列表
[x*x for x in range(1,10) if x%2==0]
使用两层循环,可以生成全排列:
[m+n for n in 'ABC' for n in 'xyz']
百融榕树运用列表生成式,可以写出非常简洁的代码。
>>>Import os //导入os模块
>>>[x for x in os.listdir(‘.‘)] // os.listdir()可以列车文件和目录
for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value。
列表生成式也可以用两个变量来生成list
百融榕树把一个list中所有的字符串变成小写
>>>L = ['Hello', 'World', 'IBM', 'Apple']
>>>[s.lower() for s in L]
百融榕树列表生成式[]中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else
百融榕树使用内建的isinstance函数可以判断一个变量是不是字符串
>>>X=123
>>>isinstance(x, str)
在Python中,这种一边循环一边计算的机制,称为生成器:generator
生成器:不必创建完整的list,从而节省大量的空间。
创建方式
百融榕树把列表生成式的[ ]改为( )便是一个生成器
>>>[ x for x in range(1,11)] //列表生成式
>>>(x for x in range(1,11)) //生成器
通过next()函数获得生成器的下一个返回值每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误.
上面这种不断调用next(g)实在是太慢了,正确的方法是使用for循环,因为generator也是可迭代对象。迭代无需关心StopIteration的错误.
for x in g:
print(x)
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
可以直接作用于for循环的对象统称为可迭代对象:Iterable
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
生成器都是Iterator对象,但list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)。
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
Python的for循环本质上就是通过不断调用next()函数实现的
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
函数本身也可以赋值给变量,即:变量可以指向函数。
函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数。
把abs指向10后,就无法通过abs(-10)调用该函数了!因为abs这个变量已经不指向求绝对值函数而是指向一个整数10!
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def add(x, y, f):
return f(x) + f(y)
调用add(-5, 6, abs)
(x) + f(y) ==> abs(-5) + abs(6) ==> 11
编写高阶函数,就是让函数的参数能够接收别的函数
Python内建了map()和reduce()函数。
map()函数接收两个参数,一个是函数,一个是Iterable(可迭代对象)
map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator((可迭代对象))返回。
>>> def f(x):
return x * x
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数
求累加运算
reduce(add, [1, 2, 3, 4]) = add(add(add(1,2),3),4)
filter()函数用于过滤序列。
filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
在一个列表中去掉偶数
用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。
filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。
sorted()函数就可以对list进行排序
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序。
>>>sorted([36, 5, -12, 9, -21], key=abs)
key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序
默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面
忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。通过str.lower()函数。
返回函数:函数作为结果值返回。
匿名函数lambda x: x * x 冒号前面的x表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2
import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
偏函数:把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
在Python中,一个.py文件就称之为一个模块(Module)
自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块
模块是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用。创建自己的模块时,要注意:
模块名要遵循Python变量命名规范,不要使用中文、特殊字符;
模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。