3

I had a broken function that should either wring all items through a function, or only run items that pass True from a qualifying function, if a qualifying function is given

def transform_dictionary(dictionary, callback, qualification_callback=None):
    return {k: callback(v) if qualification_callback and qualification_callback(v) else v for k, v in dictionary.items()}

It was broke because it required the second function to transform. I now have

def transform_dictionary(dictionary, callback, qualification_callback=None):
    if qualification_callback:
        return {k: callback(v) if qualification_callback(v) else v for k, v in dictionary.items()}
    else:
        return {k: callback(v) for k, v in dictionary.items()}

which is ugly but works. Can I do this in one line, where I either run all values through the callback, or check for truth in the second callback first and only run things that pass? Thank you

codyc4321
  • 9,014
  • 22
  • 92
  • 165

2 Answers2

6

v is only returned if there is a qualification callback and it returns False for the given value, so we can check for this condition and either return v if both conditions hold or else return callback(v).

def transform_dictionary(dictionary, callback, qualification_callback=None):
    return {k: v if qualification_callback and not qualification_callback(v) else callback(v) 
            for k, v in dictionary.items()}
Alexander
  • 105,104
  • 32
  • 201
  • 196
4

You could use a constant function as the default value instead of None:

def transform_dictionary(dictionary, callback, qc=lambda x: True):
    return {k: callback(v) if qc(v) else v for k, v in dictionary.items()}
chepner
  • 497,756
  • 71
  • 530
  • 681
  • oh, so qc always returns true, and it always runs but by default it just gets ignored. very pythony, ty – codyc4321 Jan 25 '16 at 21:35