Python 函数

常用函数

Python 函数的一些用法可以直接通过 help(函数名) 查看,例如

>>> help(abs)

abs(...)
      abs(number) -> number
      Return the absolute value of the argument.

通过 q 键退出查看

更多 API 可以直接上官网查看。

数学相关

abs() 绝对值

max()、min() 最大值和最小值 参数可以传集合,如果是 dict 就按 key 的值排序,输出的也仅是 key 。

pow() 乘方

类型转换

int()

long()

float()

str()

list()

…

字符串相关

split() 切割

capitalize() 首字母大写

··· 其实和别的语言都差不多

序列处理

这个是否常用不是很清楚,但是比较有意思,许多方法和 JavaScript 中的方法大同小异,不过感觉这个写起来更加的简洁。

filter() 过滤序列

filter(function, iterable)

例如:

1
2
>>> filter(lambda x:x%2==0, [1,2,3,4,5,6])
[2, 4, 6]

直接过滤出偶数。

zip() 并行遍历

1
2
3
4
5
>>> name = ['z','l','f']
>>> age = [1,2,3]
>>> hehe = ['q','w','r']
>>> zip(name,age,hehe)
[('z', 1, 'q'), ('l', 2, 'w'), ('f', 3, 'r')]

当集合长度不一样的时候,取最短的。如果是 dict 就只用 key 。

map() 并行遍历

有点像是上面两个函数的结合。

接收至少两个参数,第一个是函数,后面是集合。该函数是针对集合的单个元素。第一个函数可以直接是 None ,其效果就和 zip() 相同。

reduce() 归并

和上一个方法类似,但是它的函数是按顺序叠加生效的:

1
2
3
>>> listtt = range(101)
>>> reduce(lambda x,y:x+y,listtt)
5050

方法中必须是两个参数,否则会报错:

1
2
3
4
>>> reduce(lambda x,y,z:x+y+z,listtt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes exactly 3 arguments (2 given)

(上面的 stind 是 standard input 的缩写)

定义函数

Python 定义函数用 def 语句:

1
2
3
4
5
6
7
8
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def func(x):
if x>17:
print('成年了')
else:
print('小屁孩')
func(19)

注意冒号和缩进就行。

空函数

一个什么也不想做的空函数,可以用 pass 函数。

返回值

一个或者多个都行,其实多个也是一个(元组)。

函数参数

很酷!

默认参数

Python 是不支持函数的重载的。

一开始没有想明白,然后我搜了这个问题之后豁然开朗。

首先对于函数重载的重要性不用多说,支持不同类型和不同个数的参数。

但是 Python 函数本身就对参数类型没有限制,而对于不同个数,Pyhton 的处理很妙。

看段代码应该就能够理解了

1
2
3
def funcc(x,y=6):
return x*y;
print funcc(5)

结果是 30 。

1
2
3
def funcc(x,y=6):
return x*y;
print funcc(5,4)

结果是 20 。

给函数的参数设置了缺省值,不同的参数个数同一个函数执行,从而也达到了类似于重载的效果

可变参数

传入的参数个数不确定,(其实 Java 也是有的),其实就是将传入的参数封装成一个 tuple。

具体写法:

1
2
3
4
5
6
def addd(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print addd([1,2,3,4,5])

这个括号一定要加,否则会报错 TypeError: addd() takes exactly 1 argument (5 given)。

如果不想加这个括号也可以这么写:

1
2
3
4
5
6
def addd(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print addd(1,2,3,4,5)

在定义函数参数的时候加上一个星号,如果加了星号还加括号也会报错的 TypeError: can't multiply sequence by non-int of type 'list'。

如果是已经存在了一个集合,想直接传入集合:

1
2
3
4
5
6
7
def addd(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
listt = [1,2,3,4]
print addd(*listt)

这里定义中的参数前的星号和,传入的参数的星号缺一不可。

关键字参数

说是关键字参数好像也不是很准确。

像是另一种可变参数的体现。

它是将传入的参数封装成 dict 。

举个例子,当我们注册一个网站的会员时,要填写一些基本信息,通常是带星号为必须要填写的,其他的就是可选的:

1
2
3
def infoo(name,sex,**other):
print 'name:',name,'sex:',sex,'other:',other
infoo('zlf', 'male',city='hangz')

运行结果:
name: zlf sex: male other: {'city': 'hangz'}

另外,一般 Python 的习惯写法是:

可变参数用 *agrs 表示

关键字参数用 **kw 表示

递归函数

没什么特别的。

高阶函数

sorted() 又是和 JS 差不多。

除了可以正常的使用,例如:

1
2
3
>>> listtt = [32,42,32,23,21,13]
>>> sorted(listtt)
[13, 21, 23, 32, 32, 42]

还可以加个条件再排序:

1
2
3
4
5
6
7
>>> listtt = [-2,3,-1,32,-23,-54]
>>> sorted(listtt,abs)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)
>>> sorted(listtt,key=abs)
[-1, -2, 3, -23, 32, -54]

来个稍微复杂点的,给一个字典,根据 key 或者 value 来排序:

1
2
3
4
5
6
7
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0]
def by_score(t):
return t[1]
print sorted(L,key = by_name)
print sorted(L,key = by_score)

运行结果是:

1
2
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]

函数作为返回值

关于这种用法,在 JavaScript 中也是经常用到。

这个时候就需要,也必须先理解“闭包”这个概念。

这个概念我找了很多文章,但是都觉得非常的抽象以及概念化。因为之前接触最多的是 Java ,而 Java 中函数和变量完全是两个不同的东西,所以理解起来不是很顺利。

直到看到阮一峰老师的这篇介绍,举了很多例子,觉得易于理解。

我简单总结了一下。

就是通过 return 的方式将内部函数当成是变量返回给外部函数,外部函数通过这个桥梁可以读取函数内部的变量。

匿名函数

举个例子:

lambda x: x*x

就相当于

1
2
def f(x):
return x*x;

偏函数

functools 模块中的一个功能,Partial function。

例如函数 int() 可以将字符串变成整数,也可以做进制的转化:

1
2
3
4
>>> int('123',base=8)
83
>>> int('10101010010101',base=2)
10901

是将当前的数字转成 10 进制。

当我们需要重复使用转化成 2 进制这个方法的时候,就需要不停的多写一个重复的参数:

int(x,base=2)

当然首先想到的就是定义一个带默认参数的函数:

1
2
def int2(x,base =2):
return int(x,base)

这样封装之后就变得好用了。

我们说到的偏函数就是用来更加方便的创建这种类型的函数:

1
2
3
import functools
int2 = functools.partial(int,base = 2)
print int2('101')

结果当然是输出 5 。