有时候,我只是想执行一个功能项的列表 - 例如:
for x in wowList:
installWow(x, 'installed by me')
有时候,我需要这个东西模块初始化,所以我不希望有这样的全局命名空间X足迹。 一个解决办法是只是拉姆达一起使用地图:
map(lambda x: installWow(x, 'installed by me'), wowList)
但是,这当然是创建了一个很好列表[无,无,...]所以我的问题是,如果有没有返回列表类似的功能 - 因为我并不需要它。
(关当然,我也可以使用_x,因此不会留下明显的足迹 - 但地图的解决方案看起来很整齐...)
Answer 1:
您可以使用内置的any
功能,无需return语句应用功能由发电机返回的任何物品,而无需创建一个列表。 这样就可以实现这样的:
any(installWow(x, 'installed by me') for x in wowList)
我此找到您想要达到什么样的最简洁的IDOM。
在内部, installWow
功能不会返回None
其计算结果为False
的逻辑运算。 any
基本上施加or
缩小操作于由发生器返回的所有项,它们都是None
当然,所以它必须遍历由发生器返回的所有项目。 最后,它不会返回False
,但是,这并不需要打扰你。 好事是:作为一个副作用,没有创建列表。
请注意,这仅适用,只要你的函数返回的东西,计算结果为False
,例如, None
或0。如果它返回的东西,计算结果为True
,在某些时候,比如, 1
,它不会被应用到任何剩余的在你的迭代器的元素。 为了安全起见,主要使用这个成语的功能,而不return语句。
Answer 2:
你可以做你自己“每个”功能:
def each(fn, items):
for item in items:
fn(item)
# called thus
each(lambda x: installWow(x, 'installed by me'), wowList)
基本上它只是地图,但没有返回结果。 通过使用功能,您将确保“项”变量不泄漏到目前的范围。
Answer 3:
这个怎么样?
for x in wowList:
installWow(x, 'installed by me')
del x
Answer 4:
每个表达式求值的东西,所以你总是得到一个结果,无论怎样你这样做。 任何此类返回的对象(就像你的列表)将得到后来扔掉了,因为有它没有引用了。
为了澄清:Python中很少有东西是不返回任何声明。 即使是一个函数调用喜欢
doSomething()
仍返回一个值,即使它被立即丢弃。 有在蟒蛇帕斯卡功能/程序的区别没有这样的事情。
Answer 5:
你可以试试这个:
filter(lambda x: installWow(x, 'installed by me') and False, wowList)
这样一来,返回的结果是一个空列表不管。
或者您也可以删除and False
,如果你可以强制installWow()
总是返回False
(0或None
,或评估不实的另一种表现)。
Answer 6:
你可以使用过滤器和函数不返回True值。 你会得到一个空的退货单,因为过滤器只会增加其计算结果为真,我想会为你节省内存的值。 事情是这样的:
#!/usr/bin/env python
y = 0
def myfunction(x):
global y
y += x
input = (1, 2, 3, 4)
print "Filter output: %s" % repr(filter(myfunction, input))
print "Side effect result: %d" % y
运行它会产生这样的输出:
Filter output: ()
Side effect result: 10
Answer 7:
如果它是确定distruct wowList
while wowList: installWow(wowList.pop(), 'installed by me')
如果你想保持wowList
wowListR = wowList[:]
while wowListR: installWow(wowListR.pop(), 'installed by me')
如果为了事项
wowListR = wowList[:]; wowListR.reverse()
while wowListR: installWow(wowListR.pop(), 'installed by me')
虽然为这一难题的解决方案,我喜欢第一:)
Answer 8:
我无法抗拒自己张贴作为单独的答案
reduce(lambda x,y: x(y, 'installed by me') , wowList, installWow)
只有扭曲是installWow应该返回自己如
def installWow(*args):
print args
return installWow
Answer 9:
我测试了几个不同的变体,这里是我得到的结果。
Python的2:
>>> timeit.timeit('for x in xrange(100): L.append(x)', 'L = []')
14.9432640076
>>> timeit.timeit('[x for x in xrange(100) if L.append(x) and False]', 'L = []')
16.7011508942
>>> timeit.timeit('next((x for x in xrange(100) if L.append(x) and False), None)', 'L = []')
15.5235641003
>>> timeit.timeit('any(L.append(x) and False for x in xrange(100))', 'L = []')
20.9048290253
>>> timeit.timeit('filter(lambda x: L.append(x) and False, xrange(100))', 'L = []')
27.8524758816
Python 3中:
>>> timeit.timeit('for x in range(100): L.append(x)', 'L = []')
13.719769178002025
>>> timeit.timeit('[x for x in range(100) if L.append(x) and False]', 'L = []')
15.041426660001889
>>> timeit.timeit('next((x for x in range(100) if L.append(x) and False), None)', 'L = []')
15.448063717998593
>>> timeit.timeit('any(L.append(x) and False for x in range(100))', 'L = []')
22.087335471998813
>>> timeit.timeit('next(filter(lambda x: L.append(x) and False, range(100)), None)', 'L = []')
36.72446593800123
注意,时间值不是该精确(例如,前三个选项的相对性能从运行变化到运行)。 我的结论是,你应该只使用一个循环,这是更具可读性和执行至少还有替代品。 如果你想避免污染命名空间,只需del
该变量使用后。
Answer 10:
第一重写for循环作为发电机的表达,这不分配任何存储器。
(installWow(x, 'installed by me') for x in wowList )
但这种表达实际上并没有做任何事情,没有找到某种方式来使用它。 因此,我们可以重写这个产生确定性的东西,而不是依赖于可能None
结果installWow
。
( [1, installWow(x, 'installed by me')][0] for x in wowList )
它创建了一个名单,但只返回常数1.这可以方便地被消耗reduce
reduce(sum, ( [1, installWow(x, 'installed by me')][0] for x in wowList ))
这方便地返回wowList受到影响的项目的数量。
Answer 11:
只是要installWow返回None或作出最后的语句通过像这样:
def installWow(item, phrase='installed by me'):
print phrase
pass
并使用此:
list(x for x in wowList if installWow(x))
x将不会在全局命名空间中设置与返回的列表是[]单身
Answer 12:
如果你担心需要控制的返回值(你需要做的,使用过滤器 ),喜欢简单的解决方案比减少上面的例子,则可以考虑使用直接减少 。 你的功能将需要采取额外的第一个参数,但是你可以忽略它,或使用lambda丢弃它:
reduce(lambda _x: installWow(_x, 'installed by me'), wowList, None)
Answer 13:
让我说,它似乎原来的海报更关心的命名空间杂波比什么都前言本。 在这种情况下,你可以用你的工作变量单独的函数的命名空间,并声明它后调用它,或者你用“DEL”内建命令使用后,他们可以简单地从名称空间中删除它们。 或者,如果你有多个变量进行清理,高清与它的所有临时变量的函数,运行它,然后它德尔。
请仔细阅读,如果主要关注的是优化:
三个方面,可能比这里所描述别人快:
- 对于Python> = 2.7,使用collections.deque((installWow(X,“由我装”),用于wowList X),0)#保存0项,而迭代整个发电机,但是,仍然有最后的副产品连同每个项目的长度检查对象内部
- 如果担心这样的开销,安装cytoolz 。 您可以使用数仍然具有递增计数器的副产品,但也可能是环比双端队列的每个项目的检查,不知道的数量较少。 你可以使用它,而不是在未来的任何方式():
- 与itertools.imap(当installWow从未返回True否则,你可能会考虑itertools.ifilter和itertools.ifilterfalse与无作谓语)更换发电机的表达:任何(itertools.imap(installWow,wowList,itertools.repeat('由安装我')))
但真正的问题是,函数返回的东西,你不希望它返回任何东西的事实。所以要解决这个问题,你有两个选择。 一是重构代码,以便installWow需要在wowList和迭代它内部。 另一个是相当mindblowing,但你可以installWow()函数加载到像这样编译AST:
lines,lineno=inspect.getsourcelines(func) # func here is installWow without the parens
return ast.parse(join(l[4:] for l in lines if l)) # assumes the installWow function is part of a class in a module file.. For a module-level function you would not need the l[4:]
然后,您可以做同样的外部函数,并遍历AST找到for循环。 然后在的体内循环,插入instalWow()函数AST的功能定义体,匹配了变量名。 然后,您可以简单地调用的AST EXEC本身,并提供填入适当的变量命名空间字典。为了确保您的树的修改是正确的,你可以检查最终的源代码是什么样子运行astunparse 。
如果这还不够,你可以去用Cython谱写.pyx文件,该文件将生成和编译.c文件转换为Python绑定库。 然后,至少丢失周期不会花掉转换和从Python对象和类型检查一切多次。
Answer 14:
需要有人来回答 -
这里更Python的方式是不用担心污染空间,而且使用__all__
来定义公共变量。
myModule/__init__.py:
__all__ = ['func1', 'func2']
for x in range(10):
print 'init {}'.format(x)
def privateHelper1(x):
return '{}:{}'.format(x,x)
def func1():
print privateHelper1('func1')
def func2():
print privateHelper1('func1')
然后
python -c "import myModule; help(myModule);"
init 0
init 1
init 2
init 3
init 4
init 5
init 6
init 7
init 8
init 9
Help on package mm:
NAME
myModule
FILE
h:\myModule\__init__.py
PACKAGE CONTENTS
FUNCTIONS
func1()
func2()
DATA
__all__ = ['func1', 'func2']
文章来源: Is there a map without result in python?