Python:尝试在第二个参数上折叠函数映射

use*_*822 4 python functional-programming

注意:请在评论之前阅读下面的更新更新部分.这里有一些微妙之处.据我所知,所有答案都没有在上下文中起作用.

我试图找到一个模拟python'map'函数,功能略有不同.最好用例子来解释.'map'函数执行以下操作:

In [1]:    def f(x,y):
               return x+y
In [2]:    map(f, ['a','b','c'],['1','2','3'])

Out[2]:    ['a1', 'b2', 'c3']
Run Code Online (Sandbox Code Playgroud)

因此,map将f转换为新函数,我们称之为f_zipper.f_zipper压缩其参数并将f应用于每个压缩对.

我想构建的是一个函数,我称之为'magical_map',其行为如下:

In [1]:    def f(x,y):
               return x+y
In [2]:    magical_map(f, ['a','b','c'],'1')

Out[2]:    ['a1', 'b1', 'c1']
Run Code Online (Sandbox Code Playgroud)

因此,magical_map对f进行了一系列调用(第一个参数列表中的每个元素都有一个),但它会将它们全部折叠到第二个参数上.

注意:我需要一个真正实用的解决方案,可以这么说,因为我无法访问第二个参数.

即我稍后要做的是建立以下功能:

intermed_func = functools.partial(magical_map, f)
final_func = functools.partial(intermed_func, arg_I_know)
Run Code Online (Sandbox Code Playgroud)

然后可以将final_func称为

final_func(last_min_arg)
Run Code Online (Sandbox Code Playgroud)

并返回

[f(arg_I_know[0], last_min_arg), f(arg_I_know[1], last_min_arg), ...]
Run Code Online (Sandbox Code Playgroud)

我基本上都不知道如何构建'magical_map'.任何帮助都会很棒.我没有很多运气在这个问题上找到任何东西.

谢谢!

更新更新:

在上下文中解决问题要比编写一个在两个参数一次都知道时有效的函数要困难得多.问题是,在这种情况下,它们并不为人所知.更确切地说,我需要能够将以下'final_func'应用拆分为所有三个字符串.现在,使用'map'会产生以下行为.

def splitfunc(string, arg):
    return string.split(arg)

intermed_func = functools.partial(map, splitfunc)
final_func = functools.partial(intermed_func, ["a_b","v_c","g,g"])

final_func("_")

Out[xx]: [['a', 'b'], ['v_c'], ['g,g']]
Run Code Online (Sandbox Code Playgroud)

但是当我按照建议定义magical_map时(以下各方面)我会得到错误或不正确的行为.例如.

def magical_map(func, mylist, arg):
   return map(f, mylist, [arg]*len(mylist))
Run Code Online (Sandbox Code Playgroud)

然后我跑:

intermed_func = functools.partial(magical_map, splitfunc)
final_func = functools.partial(intermed_func, ["a_b","v,c","g,g"])

final_func("_")
Run Code Online (Sandbox Code Playgroud)

我明白了:

['a_b_', 'v,c_', 'g,g_']
Run Code Online (Sandbox Code Playgroud)

mgi*_*son 7

这个懒人版本怎么样:

>>> def add(x,y):
...     return x+y
... 
>>> def magic_map(func,*args):
...     return itertools.starmap(func,itertools.izip(*args))  #just zip in python 3.
...
>>> list(magic_map(add,['a', 'b', 'c'], itertools.repeat('1')))
['a1', 'b1', 'c1']
Run Code Online (Sandbox Code Playgroud)

请注意,我们需要zip采用两个系列中较短的一个,以便我们可以将无限迭代传递给任一参数,这允许我们使用扩展一个itertools.repeat.这也是懒惰的评估,所以我想你甚至可以通过2个无限的迭代,它会工作正常 - 只要你不试图实际迭代整个返回的对象;-)


这是尝试在类似于你正在做的事情的上下文中使用它(虽然我不完全理解你正在做什么,所以这可能是关闭的):

import itertools
import functools

def magic_map(func,*args):
    return itertools.starmap(func,itertools.izip(*args))  #just zip in python 3.

lst = ["a_b","v_c","g,g"]
print list(magic_map(str.split, lst, itertools.repeat('_')))

intermed_func = functools.partial(magic_map,str.split)
print list(intermed_func(lst ,itertools.repeat('_')))

final_func = functools.partial(intermed_func,lst)
print list(final_func(itertools.repeat('_')))
Run Code Online (Sandbox Code Playgroud)

输出是:

[['a', 'b'], ['v', 'c'], ['g,g']]
[['a', 'b'], ['v', 'c'], ['g,g']]
[['a', 'b'], ['v', 'c'], ['g,g']]
Run Code Online (Sandbox Code Playgroud)

这是你想要的(我想).


Tim*_*ker 6

在Python 3中:

像往常一样,这itertools是救援:

>>> import itertools
>>> list(map(f, ['a','b','c'], itertools.repeat("1")))
['a1', 'b1', 'c1']
Run Code Online (Sandbox Code Playgroud)

对于多个值,请使用 itertools.cycle()

>>> list(map(f, ['a','b','c','d'], itertools.cycle("12")))
['a1', 'b2', 'c1', 'd2']
Run Code Online (Sandbox Code Playgroud)

  • 与`zip`不同,`map`采用最长的参数 (2认同)