据廖雪峰python3教程----python学习第十一天

简介:

sorted


排序算法

     Python的内置sorted()函数可以对list进行排序:

1
2
>>>  sorted ([ 1 , 10 , 2 , 5 , 42 , 6 ])
[ 1 2 5 6 10 42 ]

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

1
2
>>>  sorted ([ 36 , 5 , - 12 , 9 , - 21 ],key = abs )
[ 5 9 - 12 - 21 36 ]

key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。对比原始的list和进过key=abs 处理的list:

1
2
3
list  =  [ 36 5 - 12 9 - 21 ]
 
keys  =  [ 36 5 ,   12 9 ,   21 ]

然后sorted()函数按照keys进行排序,并按照对应关系返回list相应的元素:


1
2
3
keys排序结果  = > [ 5 9 ,   12 ,   21 36
              |  |   |    |   | 
最终结果     = > [ 5 9 - 12 - 21 36 ]

字符排序:

1
2
>>>  sorted ([ 'bob' , 'about' , 'Zoo' , 'Credit' ])        #根据ASCII的大小比较。
[ 'Credit' 'Zoo' 'about' 'bob' ]

忽略大小写的字符串排序:

1
2
>>>  sorted ([ 'bob' , 'about' , 'Zoo' , 'Credit' ],key = str .lower)
[ 'about' 'bob' 'Credit' 'Zoo' ]
1
2
要进行反向排序,不必改动key函数,可以传入第三个函数
reverse = True :
1
2
>>>  sorted ([ 'bob' , 'about' , 'Zoo' , 'Credit' ],key = str .lower,reverse = True )
[ 'Zoo' 'Credit' 'bob' 'about' ]


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


请用sorted()对上述列表分别按名字排序:

1
2
3
>>> L = [( 'Bob' , 75 ),( 'Adam' , 92 ),( 'Bart' , 66 ),( 'Lisa' , 88 )]
>>>  def  by_name(t):
      return  t[ 0 ].lower()
1
2
3
>>> L2 = sorted (L,key = by_name)
>>> L2
[( 'Adam' 92 ), ( 'Bart' 66 ), ( 'Bob' 75 ), ( 'Lisa' 88 )]



再按成绩从高到低排序:

1
2
3
4
5
6
>>> L = [( 'Bob' , 75 ),( 'Adam' , 92 ),( 'Bart' , 66 ),( 'Lisa' , 88 )]
>>>  def  by_score(t):
      return  t[ 1 ]
>>> L2 = sorted (L,key = by_score,reverse = True )
>>> L2
[( 'Adam' 92 ), ( 'Lisa' 88 ), ( 'Bob' 75 ), ( 'Bart' 66 )]


返回函数--->函数作为返回值


高阶函数除了可以接受函数作为参数外,还可以把函数作为结果返回。

普通情况下的求和函数:

1
2
3
4
5
6
7
>>>  def  calc_sum( * args):
      ax = 0 
      for  in  args:
          ax = ax + n
      return  ax
>>> calc_sum( 1 , 2 , 3 , 5 , 4 )
15

把函数作为返回值。( 如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数: )

1
2
3
4
5
6
7
8
9
10
11
12
>>>  def  lazy_sum( * args):
      def  sum ():
          ax = 0
          for  in  args: 
             ax = ax + n
             return  ax
       return  sum
>>> f = lazy_sum( 1 , 2 , 3 , 4 , 5 )
>>> f
<function lazy_sum.< locals >. sum  at  0x026BBA08
>>>> f()
15


在上面的例子中,在函数 lazy_sum 中有定义了函数 sum ,并且,内部函数 sum 可以引用外部函数 lazy_sum 的参数和局部变量,当 laizy_sum 返回函数 sum 时, 相关参数和变量都保存在返回的函数中,这种称为 ‘闭包(Closure)’的程序结构拥有极大的威力。


当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:

1
2
3
4
5
6
7
8
9
10
11
>>>  def  lazy_sum( * args):
      def  sum ():
            ax = 0
            for  in  args:
               ax = ax + n
            return  ax
      return  sum
>>> f1 = lazy_sum( 1 , 2 , 3 , 4 , 5 )
>>> f2 = lazy_sum( 1 , 2 , 3 , 4 , 5 )
>>> f1  = =  f2
False


f1()和 f2()的调用结果互不影响。



闭包


注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。


另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

1
2
3
4
5
6
7
8
>>>  def  count():
      fs = []
      for  in  range ( 1 , 4 ): 
         def  f():
             return  i * i
      fs.append(f)
      return  fs
>>> f1,f2,f3  =  count()

每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了。

调用f1( ),f2( )和f3( )的结果应该是1,4,9,但实际:

1
2
3
4
5
6
>>> f1()
9
>>> f2()
9
>>> f3()
9


结果全部都是9,原因在于返回的函数引用了变量 i ,但它并非立刻执行。等到3个函数都返回是,它们所引用的变量 i 应经变成了

3,因此最终结果为 9 

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

如果一定要引用循环变量怎么办?方法就是在创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何改变更改,已绑定到函数参数的值不变:

1
2
3
4
5
6
7
8
9
>>>  def  count():
      def  f(j):
           def  g():
                return  j * j
           return  g
      fs = []
      for  in  range ( 1 , 4 ):
           fs.append(f(i))
      return  fs
1
2
3
4
5
6
7
>>> f1,f2,f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9

缺点就是 代码较长,可以利用lambda 函数缩短代码:

1
2
3
4
5
6
7
>>>  def  count():
      def  f(j):
           return  lambda  :j * j
      fs  =  []
      for  in  range ( 1 , 4 ):
           fs.append(f(i))
      return  fs
1
2
3
4
5
6
7
>>> f1,f2,f3 = count()
>>> f1()
1 >
>> f2()
4
>>> f3()
9


匿名函数


在Python中,对匿名函数提供了有限支持。还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:

1
2
>>>  list ( map ( lambda  x:x * x,[ 1 , 2 , 3 , 4 , 5 ]))
[ 1 4 9 16 25 ]

 

通过例子可以看出匿名函数 lambda x:x*x实际上就是:

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

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

匿名函数有个限制,就是只能有一个表达式,不用写return,表达式的值就是return

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外。匿名函数也是一个函数对象,也可以吧匿名函数赋值给一个变量,再利用变量来调用这个函数:

1
2
3
4
>>> f = lambda  x:x * x
>>> f<function < lambda > at  0x02C9FD68
>>>> f( 5 )
25

同样也可以把匿名函数作为函数的返回值:

1
2
def  bulid(x,y):
       return  lambda : x * +  y * y




本文转自 nw01f 51CTO博客,原文链接:http://blog.51cto.com/dearch/1762147,如需转载请自行联系原作者
相关文章
|
15天前
|
Python
python函数的参数学习
学习Python函数参数涉及五个方面:1) 位置参数按顺序传递,如`func(1, 2, 3)`;2) 关键字参数通过名称传值,如`func(a=1, b=2, c=3)`;3) 默认参数设定默认值,如`func(a, b, c=0)`;4) 可变参数用*和**接收任意数量的位置和关键字参数,如`func(1, 2, 3, a=4, b=5, c=6)`;5) 参数组合结合不同类型的参数,如`func(1, 2, 3, a=4, b=5, c=6)`。
14 1
|
10天前
|
Python
python学习3-选择结构、bool值、pass语句
python学习3-选择结构、bool值、pass语句
|
1天前
|
运维 Shell Python
Shell和Python学习教程总结
Shell和Python学习教程总结
|
1天前
|
Python
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
|
2天前
|
开发框架 前端开发 数据库
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
|
2天前
|
数据采集 数据可视化 数据处理
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
|
2天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
9天前
|
机器学习/深度学习 算法 Python
使用Python实现集成学习算法:Bagging与Boosting
使用Python实现集成学习算法:Bagging与Boosting
18 0
|
9天前
|
Python
python学习-函数模块,数据结构,字符串和列表(下)
python学习-函数模块,数据结构,字符串和列表
49 0
|
10天前
|
Python
python学习14-模块与包
python学习14-模块与包