[英]Filter values in a Python object array generically with a lambda function as a string
I'm working on a generic framework, and at some point I'm trying to filter variables in a generic manner. 我正在研究一个通用框架,在某些时候我试图以通用的方式过滤变量。 Take for example the following class:
以下面的课程为例:
class X:
def __init__(self, val):
self.val = val
Then I have an array of objects with arbitrary val
values: 然后我有一个具有任意
val
值的对象数组:
arr = [X("1"), X("2"), X("2"), X("3"), X("foo"), X("5"), X("3")]
My goal is to have a function which takes a lambda function and a variable names as strings (because they are user provided), which is currently implemented as follows: 我的目标是有一个函数,它将lambda函数和变量名称作为字符串 (因为它们是用户提供的),目前实现如下:
def process(lambda_f_str, var_str):
# should return [1, 2, 3, 5]
return list(set(filter(lambda x: x, map(eval(lambda_f_str), eval(var_str)))))
I want to be able to call this method with a given lambda function string that will return me only the unique integer values of these objects (In this example I'd expect [1 2 3 5]
, the order doesn't matter). 我希望能够使用给定的lambda函数字符串调用此方法,该字符串将仅返回这些对象的唯一整数值(在此示例中,我期望
[1 2 3 5]
,顺序无关紧要)。
I've tried something like this: 我尝试过这样的事情:
process("lambda x: x.val if isinstance(x.val, int) else None", "arr")
But this doesn't work since the integers are still passed as strings in my array (and I have no control over that, this is user-provided so I can't make any assumption). 但这不起作用,因为整数仍然作为我的数组中的字符串传递(我无法控制它,这是用户提供的所以我不能做任何假设)。
I wanted to do the equivalent of 我想做相同的
try:
int(x)
except:
# do something if not an int
But I don't think you can do that in a lambda function ... can you? 但我认为你不能用lambda函数做到这一点......你呢? At least I haven't found out how.
至少我还没有发现如何。
I'd be interested to see how I can write this lambda to do this filtering in a generic manner. 我有兴趣看看如何编写这个lambda来以通用的方式进行这种过滤。 I'd rather avoid changing the
process
method since this is a generic function which does other things not included in this sample code for the sake of brevity. 我宁愿避免更改
process
方法,因为这是一个通用函数,为了简洁起见,它会执行此示例代码中未包含的其他内容。
Try this... 尝试这个...
s = "lambda x: int(x.val) if x.val.isdigit( ) else None"
print process(s, "arr")
I get back... 我回来了......
[1, 2, 3, 5] [1,2,3,5]
Note that the .isdigit( )
method will fail if the numbers are given with commas or decimals. 请注意,如果数字以逗号或小数表示,则
.isdigit( )
方法将失败。
Do you really need the evals? 你真的需要逃避吗?
f = lambda x: x.val if isinstance(x.val, int) else (int(x.val) if isinstance(x.val, basestring) and x.isdigit() else None)
Not 100% proof, eg it doesn't take 123L
which is valid Python. 不是100%证明,例如它不需要
123L
这是有效的Python。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.