如何正确编写列表中的函数?

时间:2015-06-26 15:10:21

标签: python list

在Python中,我希望有一个函数可以处理不同的输入类型。像这样:

def my_square(x):
    return x ** 2

my_square(2)             #return 4
my_square(range(10))     #should return a list [0 ... 81]

npa = numpy.zeros(10)
my_square(npa)           # should return a numpy array with the squares of zeros

基本上,为标量和可迭代编写函数的好习惯是什么?这可以用* args或* kwargs来完成吗?

4 个答案:

答案 0 :(得分:0)

执行此操作的典型方法是使用numpy.asarray将您的函数输入转换为ndarray。如果输入是标量,则结果是具有0维的数组,其行为基本上类似于Python数字类型。例如:

def square(x):
    x = np.asarray(x)
    return x**2

那样:

>>> square(4)
16
>>> square([1, 2, 3, 4])
array([ 1,  4,  9, 16])

请注意,我将列表作为输入并收到ndarray作为输出。如果绝对必须接收与输入相同类型的输出,您可以在返回之前转换结果:

def square(x):
    in_type = type(x)
    x = np.asarray(x)
    return in_type(x**2)

但这会带来额外的成本,但收效甚微。

答案 1 :(得分:0)

由于Python是动态类型的,并且Python的设计理念违背了在调用函数时希望区别显而易见的想法,因此不会将其视为 Pythonic 。但是,如果必须的话,您可以使用isInstance()方法来完成您想要的任务。例如:

def mySquare(x):
    if isinstance(x, int):
        return x**2
    elif isinstance(x, range):
        return [i ** 2 for i in x]

print(mySquare(2)); //4
print(mySquare(range(10))); //[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

IDEOne link here.

然而,仅仅因为你可以做某事,并不意味着你应该做。

Refer to this question for further information on isinstance,我建议您同时查看Duck Typing

此外,single dispatch function也可能提供您所需要的内容,但我没有足够的经验为此提供解释,但是,这可能是您想要查看的内容。

答案 2 :(得分:0)

这样做会更好,而且更容易维护:

def foo(n):
    return n ** 2

然后在需要时构建列表,dicts等(我不是很熟悉numpy,但我想你可以做类似的事情):

foo_list = [foo(n) for n in range(10)]
foo_dict = {n: foo(n) for n in range(10)}

似乎有numpy使用numpy.fromiter()。来自文档:

iterable = (foo(n) for n in range(5))
foo_arr = np.fromiter(iterable, np.whatever_numpy_datatype)
如果你真的需要,你甚至可以将它们变成功能:

def foo_list(start=0, stop=0):
    return [foo(n) for n in range(start, stop)]

def foo_dict(start=0, stop=0):
    return {n: foo(n) for n in range(10)}

另一个选择是,要求宽恕比获得更容易:

def foo(scalar_or_iter):
    try:
        return [n ** 2 for n in scalar_or_iter]
    except TypeError:
        return scalar_or_iter ** 2

答案 3 :(得分:0)

正如评论中所建议的,只需编写函数的标量版本,并使用map for lists etc和imap for iterables(map不适用于那些):

map(myFunc,myList)

import itertools
itertools.imap(myFunc,myIterable)