pydata

Keep Looking, Don't Settle

*args and **kvargs in python

今天在写Jimmy的calc engine的时候发现的一个问题:第一遍draft code的时候没有使用函数,而是直接一行行的写,每一个变量都有一个名字。写完以后需要整理成python的function,这样可以通用化。

但是一个问题是:当把新的data传进函数的时候,比如新的data是pandas dataframe的每一行,这个时候要么把每一行的不同列都分别赋值给函数的参数,能不能把这一行当作一个整体,比如是一个list传递进去?答案是肯定的。就是需要用__args__(顺便说一下 __*kvargs__)

import pandas as pd
import numpy as np

def test(a, b, c, e):
    return a

np.random.seed(9999)
np_array = np.random.randint(0, 10, 20).reshape((5, 4))
print df
[[6 1 6 5]
 [5 9 6 8]
 [0 8 1 5]
 [3 1 0 6]
 [4 4 6 8]]

test函数有4个参数,它的目的是返回第一个参数

np_array是一个5*4的array,现在想把每一行都作为test的参数传进去。如果直接把np_array的一行放进去肯定不行:一行是一个list,但是test函数需要4个参数。

这个时候在list前面加个 * 就可以解决

for i in np_array:
    print test(i)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-22-d2259d52cb20> in <module>()
      1 for i in np_array:
----> 2     print test(i)


TypeError: test() takes exactly 4 arguments (1 given)
for i in np_array:
    print test(*i)
6
5
0
3
4

kvargs__ 或者 __kwargs 是传入key value的组合。

def test(**kvargs):
    for key in kvargs:
        print "key = %s ,  value = %s" % (key, kvargs[key])

test(x = 3, y = 5, z = 8)

key = y ,  value = 5
key = x ,  value = 3
key = z ,  value = 8

还可以把 *args , __kvargs__一起作为函数的参数,但是一定要注意的是:传进真实参数的时候,要跟__*args__ __kvargs__的顺序一致,否则会报错。