doubleE
doubleE

Reputation: 31

How do I combine the following comprehension in Python?

I have two dictionaries created using dict comprehension. I am wondering if (a) there's a way to build it in a single pass, (b) is it advisable? and (c) is there a better approach?

templates_gray = {k:cv2.imread(v, 0) for (k, v) in static_templates.items()}

img_dimension = {k:v.shape for (k, v) in templates_gray.items()}

Upvotes: 3

Views: 85

Answers (3)

new Q Open Wid
new Q Open Wid

Reputation: 2313

For (a), I would say to check the top answer, for (b), I would say, the answers are one-liners but these are basically hard to read for me. So I recommend to expand them out to make more sense. For (c), other than Jacinator's answer which actually defines a function and not just a single line of code, I don't know. I would say there might be not any but that is just my conjecture. And, it depends on your definition of "best".

Upvotes: 0

Jacinator
Jacinator

Reputation: 1413

A) You most certainly can do it in one line. On your second iteration you're really only getting an attribute for each value in your dictionary.

img_dimension = {k: cv2.imread(v, 0).shape for k, v in static_templates.items()}

B) It is getting a bit harder to read and I don't think I would do exactly that. You can do comprehensions over multiple lines, which might help a bit.

img_dimension = {
    k: cv2.imread(v, 0).shape
    for k, v in static_templates.items()
}

C) I think what I would do is combine the comprehension with a function. This keeps the logic out of the comprehension and I think is easier to read. I don't know if defining a function will break your desire for a single line of code or not.

def get_shape(v):
    x = cv2.imread(v, 0)
    return x.shape

img_dimension = {k: get_shape(v) for k, v in static_templates.items()}

Note: This assumes that templates_gray isn't something you need to use later.

Upvotes: 2

Prune
Prune

Reputation: 77910

Do the direct substitution of the upper expression for templates_gray:

img_dimension = {k:v.shape for (k, v) in 
                    {k:cv2.imread(v, 0) for (k, v) in
                         static_templates.items()  
                    }.items()
                }

The advisability depends entirely on your usage and maintenance environment. I find this one-line version to be less readable. At the very least, it needs a comment to explain the holistic effect.

Upvotes: 1

Related Questions