python 函数

一,函数的定义

def a(args):

    pass
函数代码块以def关键字开头,+ 函数名+ (参数):
然后第一行内容应该缩进,然后写我们自己的代码逻辑
return 关键字     代表函数执行完返回的值
pass           关键字,代表什么都不干
exit(num)           强行退出
例子:
def add(x, y):

    print(“x  + y  = {0}”.format(x+y))

调用:函数名(参数)

print(add(1,2))   结果为:3

二,参数类型

我们经常在看别人的代码中,经常出现def(*args, **kwargs)这样的表现形式:
*args                  tuple  (1, ) 元组
**kwargs           dict   {“k”: “v”} 字典

三,匿名函数

关键字lambda表示匿名函数,冒号前面的x表示函数参数。

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

如:a = lambda x,y:x+y

print(a(1,2)) 结果为:3

四,高阶函数

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

1,map() 

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

实例:

f = lambda x:x+x
b = map(f,[1,2,3,4])
print(list(b)) 结果为:[2, 4, 6, 8]

2,reduce()

reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

def add(x,y):
    return x+y
a = reduce(add,[1,2,3,4])
print(a)
结果为:10
3,filter()过滤
filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

如:在一个list中,删掉偶数,只保留奇数。

首先定义一个函数,打印除以2余1的数字,即打印奇数。

def is_odd(n):
    return n % 2 == 1

print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])))

结果为:[1, 5, 9, 15]

4,sorted() 排序

排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。

sorted(iterable, key, reverse) 

 iterable 一个可迭代的对象 
 key 对什么进行排序 
 reverse bool类型,如果为true为反序, 默认为false ,也就是默认为从小到大。
 返回值是一个list 

(1)对列表进行排序。

a=[-1,3,2]
print(sorted(a))
结果为:[-1, 2, 3]
如果要从大到小则:
a=[-4,3,2]
print(sorted(a,reverse=True))
结果为:[3, 2, -4]

(2)sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

a=[-4,3,2]
print(sorted(a,key=abs))
结果为:[2, 3, -4]
(3)字符串排序,默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能用一个key函数把字符串映射为忽略大小写排序即可。忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。这样,我们给sorted传入key函数,即可实现忽略大小写的排序:

print(sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower))
结果为:['about', 'bob', 'Credit', 'Zoo']

实例:假设我们用一组tuple表示学生名字和成绩:L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

用sorted()对上述列表按分数从大到小排序:

print(sorted(L,key=lambda x:x[1],reverse=True))
结果为:[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]

(4)对字典进行排序,按照value进行排序。

L = dict([('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)])
print(sorted(L.items(),key=lambda x:x[1],reverse=True))
结果为:[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
在这里使用了items():因为寻常遍历字典只会对“key”进行,要先使用此
方法将每个key:value对取出,然后进行操作。
可以看见结果返回的是一个列表,返回字典的话需要进行类型转换。如:
print(dict(sorted(L.items(),key=lambda x:x[1],reverse=True)))
{'Adam': 92, 'Lisa': 88, 'Bob': 75, 'Bart': 66}

五,生成式与生成器

1,列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

格式:  [exp for val in collection if condition]

举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):

print(list(range(11)))
结果为:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循环:

a=list()
for i in range(1,11):
    a.append(i*i)

print(a)

结果为:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:

a = [x*x for x in range(11)]
print(a)
结果为:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来。

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

a = [x*x for x in range(11) if x % 2 == 0]
print(a)
结果为:[0, 4, 16, 36, 64, 100]
还可以使用两层循环,可以生成全排列:
print([m + n for m in "abc" for n in "123"])
结果为:['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
2.生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。

(1)第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

(exp for val in collection if condition)

如:生成式:

a = [x for x in range(3)]

print(a)

结果为:[0, 1, 2]

生成器:

b = (x for x in range(3))
print(b)
结果为 :<generator object <genexpr> at 0x00000216B4BF72B0>

创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。
我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?
如果要一个一个打印出来,可以通过
next()函数获得generator的下一个返回值:

b = (x for x in range(3))
print(next(b))
结果为:0
generator保存的是算法,每次调用next(b),就计算出b的下一个元素的值,
直到计算到最后一个元素
b = (x for x in range(3))
print(next(b))
print(next(b))
print(next(b))
结果为:0 
    1
     2
正确的方法是使用for循环,因为generator也是可迭代对象:
b = (x for x in range(3))
for i in b:
    print(i)
结果为:0
     1
     2

(2)方法二:使用yield关键字,包含yield语句的函数会被特地编译成生成器。yield可以
理解成return,但是并不退出,只是挂起,恢复的时候从yield下面开始执行。

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)
a = odd()
next(a)
next(a)
next(a)
结果为:step 1
    step 2
    step 3



阅读更多

没有更多推荐了,返回首页