简体   繁体   English

Python:从lambda闭包列表中删除

[英]Python: Removal from a list of lambda closures

I have confused myself up to the point I need help: 我一直困惑自己,直到我需要帮助:

Suppose I have a list of closures to be executed. 假设我有一个要执行的闭包列表。 Upon execution of such a closure, if a certain condition is met I want it to remove itself from the list. 在执行这样的关闭后,如果满足某个条件,我希望它从列表中删除自己。 Consider the following: 考虑以下:

my_lambdas = []

def some_condition_is_met(n): return n > 5

def my_function(n):
    if some_condition_is_met(n):
        # Remove me from my_lambdas, but how?
        return False
    print(n)
    return True

def make_me_a_lambda(n):
    # Alternatively do removal based on the return value:
    return lambda: my_function(n) or remove_me_but_how() 

my_lambdas.append(make_me_a_lambda(1))
my_lambdas.append(make_me_a_lambda(7))

for l in my_lambdas: l()

In reality I don't have control over the execution the lambdas myself, so I can't say something like: 实际上,我自己无法控制lambda的执行,因此我不能说类似以下内容:

my_lambdas = [l for l in my_lambdas if l()]

Although I guess it would be possible to wrap the execution of the lambdas in a function I do have control over and pass only that single wrapper function to the host application, if possible I'd like to avoid that additional indirection. 尽管我猜想可以将lambda的执行包装在我可以控制的函数中,并且仅将单个包装函数传递给主机应用程序,但如果可能的话,我想避免这种额外的间接调用。

Any help is much appreciated, thanks! 非常感谢任何帮助,谢谢!

Could you structure it like so: 您可以这样构造它吗:

delenda = []
for l in my_lambdas:
   if not l(): delenda.append(l)
for item in in delenda:
   my_lambdas.remove(item)

And just use the truthiness of the return value to remove the items at execution time? 只是使用返回值的真实性在执行时删除项目?

Alternatively, could you pass callable class instances that knew how to delete themselves from a registry? 或者,您可以传递知道如何从注册表中删除自身的可调用类实例吗?

from functools import partial

class Deleteme (object):
    REGISTRY = []
    def __init__(self, func, *args):
        self.callable = partial(func, *args)

    def register(self):
        if not self in self.REGISTRY: self.REGISTRY.append(self)

    def __call__(self):
        retval = self.callable()
        if not retval and self in self.REGISTRY:
            self.REGISTRY.remove(self)
        return retval

    @classmethod
    def run_lambdas(cls):
        for lmb in [i for i in cls.REGISTRY] :
            yield lmb()


test1 = Deleteme (lambda q: q > 5, 3)
test2 = Deleteme (lambda q: q > 5, 6)
test3 = Deleteme (lambda q: q > 5, -1)
test1.register()
test2.register()
test3.register()

for item in Deleteme.run_lambdas():
    print item

print Deleteme.REGISTRY
>False
>True
>False
>[<__main__.Deleteme object at 0x00000000026A0048>]  #note only one left in the list

The your 'my_lambdas' will be Deletem.REGISTRY (if ypu want to be tidy you should probably wrap that in a function - asking outside classes to read and write to shared fields directly is Bad Practice, but I'm lazy :) 'run_lambdas' would do the loop-and-remove. 您的“ my_lambdas”将是Deletem.REGISTRY(如果ypu要整理,您应该将其包装在函数中-要求外部类直接读写共享字段是不好的做法,但是我很懒:)'run_lambdas '会进行循环删除。

USER ADVISORY - code tested by running exactly once :) 用户咨询-通过仅运行一次就对代码进行了测试:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM