将函数映射或应用到单个值-在Python 3中执行的正确方法

时间:2019-02-22 20:43:45

标签: python iterator

在我的python项目中,在很多地方出现的功能严格等同于:

def map_or_single(item,func, iterative_classes, *args ):

   if isinstance(item, iterative_classes):
       for k in item:
           func(k, *args)
       return
   func(item, *args)

但是我确定必须有一些Python(3?)内置函数来完成这项琐碎的任务,我不想发明一辆自行车并在项目中使用这种废话。任何人都知道适当的内置功能吗?

4 个答案:

答案 0 :(得分:3)

完全不要尝试编写此代码。代替

map_or_single(item, func, ...)

只写

def mapper(func, items, *args):
    for k in items:
        func(k, *args)

mapper 总是获取一个列表(或其他可迭代的列表);如有必要,由调用方提供。

mapper(f, [1,2,3,4])
mapper(f, [1])  # Not mapper(f, 1)
mapper(f, some_tree_object.depth_first_iterator())
mapper(f, some_tree_object.breadth_first_iterator())

答案 1 :(得分:1)

这是明确的antipattern,因此在Python(或大多数,如果不是所有其他语言)中,没有“适当”或“正确”的方式来做到这一点。您当然可以想出各种各样的脆性解决方案,但是从长远来看,这种类型的问题会导致错误,而带来的好处却很小。

通过完全避免使用此模式并要求用户输入符合一种模式而不是两种或更多种模式,可以解决此问题。

代替此界面:

map_or_single(single, func, ...)
map_or_single(iterable, func, ...)

您具有以下界面:

map_or_single([single], func, ...)
map_or_single(iterable, func, ...)

要求包装单个值是要付出的一小笔费用,以避免这种模式很容易引起所有潜在的麻烦。

很明显,如果情况允许:

func(single)
map(func, iterable)

答案 2 :(得分:0)

我很确定没有内置任何代码。我的项目中有这个辅助功能;

def any2list(val):
    if isinstance(val, (str, bytes)):
        val = [val]
    try:
        iter(val)
    except TypeError:
        val = [val]
    return list(val)

此功能的目标是将任何输入转换为list。如果给定一个元素,则返回该元素的列表。

我在其他功能中使用了此功能

def map_or_single(container, func, *args):
    container = any2list(container)
    for k in container:
        func(k, *args)

,现在container参数可以是适当的容器类型(例如list),也可以是单个元素(标量),例如int。我发现这种策略很干净,因为我没有明确担心单个元素的情况。

注意:我选择特殊对待strbytes,以便any2list不会将单词或句子拆分为单个字母,这几乎总是我想要的。您的用例可能有所不同。

答案 3 :(得分:0)

您可以使用函数map()partial()

from functools import partial
from operator import add

l = [1, 2, 3]

result = map(partial(add, 2), l)

print(list(result))
# [3, 4, 5]