If the language supports it, I usually use labeled anonymous functions to accomplish this.
someCondition = lambda p: True if [complicated expression involving p] else False #I explicitly write the function with a ternary to make it clear this is a a predicate if (someCondition(p)): #do stuff... IMHO this is a good compromise because it gives you the readability benefit of not having the complicated expression cluttering the if while avoiding clutering the global/package namespace with small throwaway labels. It has the added benefit that the function "definition" is right where its being used making it easy to modify and read the definition.
It doesn't have to only be predicate functions. I like to encase repeated boiler-plate in small functions like this as well (It works particularly well for pythonic list generation without clutering the bracket syntax). For example, the following oversimplified example when working with PIL in python
#goal - I have a list of PIL Image objects and I want them all as grayscale (uint8) numpy arrays im_2_arr = lambda im: array(im.convert('L')) arr_list = [im_2_arr(image) for image in image_list]