127 python dictionary functional-programming
这非常难以理解,但我正在尝试学习/理解python中的函数式编程.以下代码:
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]
def maptest(foo, bar):
print foo, bar
map(maptest, foos, bars)
Run Code Online (Sandbox Code Playgroud)
生产:
1.0 1
2.0 2
3.0 3
4.0 None
5.0 None
Run Code Online (Sandbox Code Playgroud)
问:有没有办法在python中使用map或任何其他功能工具来生成以下没有循环等.
1.0 [1,2,3]
2.0 [1,2,3]
3.0 [1,2,3]
4.0 [1,2,3]
5.0 [1,2,3]
Run Code Online (Sandbox Code Playgroud)
正如附注所示,如果foo和bar之间存在依赖关系,实现将如何变化.例如
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)
并打印:
1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...
Run Code Online (Sandbox Code Playgroud)
PS:我知道如何使用if,循环和/或生成器天真地做,但我想学习如何使用功能工具实现相同的功能.是仅仅在maptest中添加if语句或在maptest内部将另一个过滤器映射应用于条形图的情况?
Joh*_*uhy 194
您熟悉其他功能语言吗?即,您是否正在尝试学习python如何进行函数式编程,或者您是否正在尝试学习函数式编程并使用python作为工具?
另外,你了解列表理解吗?
map(f, sequence)
Run Code Online (Sandbox Code Playgroud)
直接等价于(*)到:
[f(x) for x in sequence]
Run Code Online (Sandbox Code Playgroud)
事实上,我认为map()
曾经计划从python 3.0中删除多余(没有发生).
map(f, sequence1, sequence2)
Run Code Online (Sandbox Code Playgroud)
大致相当于:
[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]
Run Code Online (Sandbox Code Playgroud)
(它处理序列长度不同的情况有所不同.如您所见,map()
当其中一个序列用完时填充无,而zip()
当最短序列停止时则填写)
因此,要解决您的具体问题,您需要尝试生成结果:
foos[0], bars
foos[1], bars
foos[2], bars
# etc.
Run Code Online (Sandbox Code Playgroud)
您可以通过编写一个带有单个参数并打印它的函数来执行此操作,然后执行以下操作:
def maptest(x):
print x, bars
map(maptest, foos)
Run Code Online (Sandbox Code Playgroud)
或者,您可以创建一个如下所示的列表:
[bars, bars, bars, ] # etc.
Run Code Online (Sandbox Code Playgroud)
并使用您原来的maptest:
def maptest(x, y):
print x, y
Run Code Online (Sandbox Code Playgroud)
一种方法是事先明确地建立列表:
barses = [bars] * len(foos)
map(maptest, foos, barses)
Run Code Online (Sandbox Code Playgroud)
或者,您可以拉入itertools
模块. itertools
包含许多聪明的函数,可以帮助您在python中进行函数式的惰性求值编程.在这种情况下,我们希望itertools.repeat
,当您迭代它时,它将无限期地输出其参数.最后一个事实意味着,如果你这样做:
map(maptest, foos, itertools.repeat(bars))
Run Code Online (Sandbox Code Playgroud)
你将得到无穷无尽的输出,因为map()
只要其中一个参数仍在产生输出就会继续.但是,itertools.imap
就像map()
,但是一旦最短的可迭代停止就停止.
itertools.imap(maptest, foos, itertools.repeat(bars))
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助 :-)
(*)它在python 3.0中有点不同.在那里,map()基本上返回一个生成器表达式.
sth*_*sth 54
最简单的方法是不要bars
通过不同的功能,而是直接从maptest
以下方式访问它:
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]
def maptest(foo):
print foo, bars
map(maptest, foos)
Run Code Online (Sandbox Code Playgroud)
使用原始maptest
函数,您还可以使用lambda函数map
:
map((lambda foo: maptest(foo, bars)), foos)
Run Code Online (Sandbox Code Playgroud)
Jas*_*ker 30
这是您正在寻找的解决方案:
>>> foos = [1.0, 2.0, 3.0, 4.0, 5.0]
>>> bars = [1, 2, 3]
>>> [(x, bars) for x in foos]
[(1.0, [1, 2, 3]), (2.0, [1, 2, 3]), (3.0, [1, 2, 3]), (4.0, [1, 2, 3]), (5.0, [
1, 2, 3])]
Run Code Online (Sandbox Code Playgroud)
我建议使用list comprehension([(x, bars) for x in foos]
部分)而不是使用map,因为它避免了每次迭代时函数调用的开销(这可能非常重要).如果你只是想在for循环中使用它,你将通过使用生成器理解获得更好的速度:
>>> y = ((x, bars) for x in foos)
>>> for z in y:
... print z
...
(1.0, [1, 2, 3])
(2.0, [1, 2, 3])
(3.0, [1, 2, 3])
(4.0, [1, 2, 3])
(5.0, [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
不同之处在于生成器理解是延迟加载的.
更新 回应此评论:
当然你知道,你没有复制条,所有条目都是相同的条形列表.因此,如果您修改其中任何一个(包括原始条),则修改所有这些.
我想这是一个有效的观点.我能想到有两种解决方案.最有效的可能是这样的:
tbars = tuple(bars)
[(x, tbars) for x in foos]
Run Code Online (Sandbox Code Playgroud)
由于元组是不可变的,这将阻止通过此列表理解的结果修改条形(或者如果你去那条路线则生成器理解).如果您确实需要修改每个结果,可以执行以下操作:
from copy import copy
[(x, copy(bars)) for x in foos]
Run Code Online (Sandbox Code Playgroud)
但是,就内存使用和速度而言,这可能有点贵,所以除非你真的需要添加它们,否则我建议不要这样做.
Dus*_*tin 20
函数式编程是关于创建无副作用的代码.
map是一个功能列表转换抽象.你使用它来获取一些东西并将其转换为其他东西的序列.
您正在尝试将其用作迭代器.不要那样做.:)
以下是如何使用map构建所需列表的示例.有更短的解决方案(我只是使用理解),但这将有助于您了解哪些地图做得更好:
def my_transform_function(input):
return [input, [1, 2, 3]]
new_list = map(my_transform, input_list)
Run Code Online (Sandbox Code Playgroud)
请注意,此时您只进行了数据操作.现在你可以打印出来了:
for n,l in new_list:
print n, ll
Run Code Online (Sandbox Code Playgroud)
- 我不确定你的意思是'没有循环'.fp不是关于避免循环(你不能检查列表中的每个项目而不访问每个项目).这是为了避免副作用,从而减少错误.
Rob*_*let 12
>>> from itertools import repeat
>>> for foo, bars in zip(foos, repeat(bars)):
... print foo, bars
...
1.0 [1, 2, 3]
2.0 [1, 2, 3]
3.0 [1, 2, 3]
4.0 [1, 2, 3]
5.0 [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
Ign*_*ams 11
import itertools
foos=[1.0, 2.0, 3.0, 4.0, 5.0]
bars=[1, 2, 3]
print zip(foos, itertools.cycle([bars]))
Run Code Online (Sandbox Code Playgroud)