有没有地图,而结果蟒蛇?(Is there a map without result in pyth

2019-06-24 22:12发布

有时候,我只是想执行一个功能项的列表 - 例如:

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”内建命令使用后,他们可以简单地从名称空间中删除它们。 或者,如果你有多个变量进行清理,高清与它的所有临时变量的函数,运行它,然后它德尔。

请仔细阅读,如果主要关注的是优化:

三个方面,可能比这里所描述别人快:

  1. 对于Python> = 2.7,使用collections.deque((installWow(X,“由我装”),用于wowList X),0)#保存0项,而迭代整个发电机,但是,仍然有最后的副产品连同每个项目的长度检查对象内部
  2. 如果担心这样的开销,安装cytoolz 。 您可以使用数仍然具有递增计数器的副产品,但也可能是环比双端队列的每个项目的检查,不知道的数量较少。 你可以使用它,而不是在未来的任何方式():
  3. 与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?