Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29308659
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Python/Ruby

2010-06-12 09:40:00

applymap及函数工具、list的再构造

                                                               时间:2010-6-12

python中,有两种方式可以用来定义一个函数。用def可以定义有名字的函数。用lambda可以定义匿名函数。由于在实际调用一个函数时,实参的个数可能是一个也可能是两个,还可能是多个。因此在形参前面加上***来处理这个情况。

笔记:哦明白了*** 经常会在类中看到原来是定义可变长的参数列表的!

示例:

>>> def test(*x):

...     if len(x) > 0:

...             for c in x:

...                     print c

...     else:print None

这样就可以定义可变长度的一个参数列表了。就可以如下调用它!

test();也可以使用一个实参的形式调用,比如:test(4);还可以以多个实参的形式调用,比如:test(1,2,3,4)

但不管是哪种方式,在调用的时候实际参数的个数都已经确定下来了,一个就是一个,两个就是两个。现在假设在一个程序中有一 个list,比如叫userInput,这个list中的成员是由用户在使用程序时交互确定的,在运行中可能有一个成员,也可能有多个成员,这一切都要看 用户怎么操作。现在要用test函数把userInput打出来。

笔记:当要传入一个序列的时候可能就会出现个数不确定的情况了。要打印的话也是整个序列了。怎么办呢?

python中还有更简单的办法,就是使用内置函数apply

  • apply(test, userInput)

表示把userInput作为test的参数,也就是说比如在程序运行时,userInput得到的值是[1,2,3],那么就相当于test(1,2,3)。如果userInput得到的实际值是[1,2],那么就相当于test(1,2)

>>> userinput=[1,2,3]

>>> apply(test,userinput)

1

2

3

笔记:还记得上次那个JS培训不?里面讲到一个arguments对象了吧。感觉这个与那是一个道理的。因为用户的实参个数是不固定的。所以我们可以使用这个关键字进行处理!

总之,定义函数时在形式参数面前加上***是为了,在调用这个函数的时候可以灵活地提供实参的个数。而apply则是为了可以用不定个数的实际参数来调用函数。

笔记:我们在处理这种可变长参数的时候就非常有效了!

 

 

 

 

更进一步:

其实还可以更简单,连apply都不用,直接写成:

  • test(*userInput)

这表示的意思就是apply(test,userInput)

>>> test(*userinput)

1

2

3

笔记:我感觉这样处理的话将实参与形参捆绑处理了。

 

可以把函数定义的中形参前面的*理解为打包操作,也就是把多余的实参都打包在一个tuple;可以把调用时的*理解 为解包的操作,比如说这里表示:调用test函数,实参是对userInput解包后所得的东西。当然对于**也可以以相同的方式理解。在 test(**D)的形式中,D必须为一个dictionrary,相当于test(key1=value1,key2=value2...)

 

笔记:

明白了!!!!

*   表示的是tuple

**  表示的是字典

函数形参如果这样写* 就表示这个参数接收可变长的tuple参数

如果形参这样写** 就表示接收可变长的字典类型的参数!

 

介绍一下map函数

map(function, seq1,seq2...)

map实际上是python中一大类函数的一个代表,这类函数可以被称为函数工具。常用的函数中,同类的还有filterreduce

  • filter(func or None,seq)

它返回一个序列类型的值。表示把seq中的每个成员依次代入function中,如果为真则它将成为返回序列中的一个成员。

再来看reduce函数:

  • reduce(function, sequence[, initial])

表示把sequence按照function提供的规则进行计算,最后算出一个值来。这个function必须具有两个参数,

 

>>> L = [1,2,3,4,5]

>>> reduce((lambda x,y: x*y),L)

120

含义:相当把L里面的数据作一次运算处理。这个运算是一个

 

从上面介绍可以看出,mapfilter或者reduce实际都是对序列类型数据的成员进行操作。由于这种操作在python是非常普遍的,因此在python 2.0后提供了一种叫"list的再构造"的语法形式来进行类似的操作。

示例:

>>> L = [1,2,3,4,5]

>>> map((lambda x:x**2),L)

[1, 4, 9, 16, 25]

理解:map的工具相当于是把L里面的全部的元素均丢到这个定义的函数里面去处理。也是处理一个sequence类型的数据。现在好了。我们可以使用一种叫做:list的再构造

>>> [x**2 for x in L]

[1, 4, 9, 16, 25]

哦!!!终于看清楚了庐山真面目了。哈哈~~~

原来还可以写map的哦!

 

[x**2 for x in L]   ===> [1,4,9,16]

首先,这个表达式用[]括起来了,表示这个表达式返回的结果是一个list。其次,后面一部分,也就是for x in L,很明显是把L中的成员依次取出来。第三,前面一部分,也就是x**2,表示对x的操作是"平方"。然后以每次计算后的值作为目标list的成员。其实 可以把这一部分看成是目标list通项公式,通过对这个通项公式代入不同的值,可以得到不同的结果。而这个不同的值就是由后面的部分,即 for x in L,确定的。

 

更强大的一个功能:

当然大名顶顶的"list再构造"还有别的功能,它可以加上条件从句(if语句),比如:

  • [x**2 for x in L if x%2==0] ===>[4,16]

"list再构造"还可以嵌套for这一部分

看到没有……提取出来的数据还可以带条件提取的哦!!!!强强强

 

"list再构造"还可以嵌套for这一部分,比如:

  • [x*y for x in L for y in L] ===> [1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16]

做了两个构造处理!python一个字简洁

 

 

这个式子已经相当复杂,因此在以程序可读性著称的python世界中,最好不要使用这种东西。不过,也可见用list再构造也可以实现for或者mapfilter的功能,但是list再构造的效率最高,其次mapfilter这些内置函数,再次才是for

 

结论:尽可能使用 list再构造!

 

阅读(594) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-06-12 20:53:50

目标:精通JAVA编程 领域:分布式缓存领域。 珍惜时间。严格按计划去实施