Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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:

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:

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).

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? 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. 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.

share|improve this question
 
Can you write an isint() function and do process("lambda x: x.val if isint(x.val) else None", "arr")? –  Lev Levitsky May 11 '12 at 18:00
 
I thought about that, I'll probably have to settle with this if i don't find anything else, but initially i wanted to avoid this since my lambda strings are defined by the user who doesn't know that i defined a method called isint. Of course this could be part of documentation or comment to let the user know, but I wanted to know if there's a better way to do this, otherwise that's probably what I'll have to do. –  Charles Menguy May 11 '12 at 18:02
 
Don't use variable names like that, and don't use a class like that. Just use a dict with the keys as the user input and the value as what you want to filter by –  Daenyth May 11 '12 at 18:10
add comment

2 Answers

up vote 0 down vote accepted

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, e.g. it doesn't take 123L which is valid Python.

share|improve this answer
add comment

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]

Note that the .isdigit( ) method will fail if the numbers are given with commas or decimals.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.