Building a Medical Data Validator: un-comprehend a bit code

I don’t understand what this is doing. Can someone un-comprehend it so that I can understand what it’s doing? I also don’t understand when to use bracket notation in this manner, or why brackets are being used instead of parentheses. I don’t know if I’ve missed something somewhere, but this lab seemed to have flown right over my head in the last 7 or 8 steps.

This was the answer to step 39:

return [key for key, value in constraints.items() if not value]

I think: since .items() is going to return the key:value pair we are wanting it to return a key for each key where the value does not match the value. Where the “value” is a falsey return from a prior comparison in the prior for loop?

If what I think is correct, what is the process of how you end up with that logic? Is there a good resource for learning how to think in those logical steps? I thought I was doing pretty good, but then hit a wall with this lab, which I suppose is the natural process in learning anything, though discouraging. Kind of wish there was more homework between lectures…

1 Like

this is how the iteration goes, we get a key, value for each item in constaints.items()

then you have key and if not value, that means that key will be part of the new list, if not value is True, so that means if value is a falsy value

in the general medical validator, that means that if the constraint fails for that specitfic property, the key is added to the list of properties failing validation

Why is it inside brackets instead of parenthesis? No wait, it’s returning a list so that’s why it is bracketed… If it were in parenthesis would it return a tuple?

I was in an incorrect frame of mind, thinking of grouping instead of… would operators be the correct way to describe it?

Is that also what the lecture meant when it said you can create a dictionary without assigning it a variable? It created a list without assigning it a variable because the contents of the list don’t need to be saved, only passed on to the next step in the function?

no, Python does not support tuple comprehension, if you want a tuple you would need to use tuple() like

p = [1, 2, 3, 4]
t = tuple(x*2 for x in p)

(x*2 for x in p) is a generator

Don’t be discouraged at all! What you are experiencing is completely normal. List comprehensions cram a lot of logic into a single line, making them incredibly hard to read when you are first learning.

To help you “un-comprehend” it, here is exactly how that single line looks written out as a traditional for loop:

python

# What the comprehension is doing under the hood:
failed_constraints = []

for key, value in constraints.items():
    if not value:  # If the validation failed (is Falsy)
        failed_constraints.append(key)

return failed_constraints

Use code with caution.

To answer your question about variables: Yes, your mindset is exactly right! You don’t need to assign the list to a temporary variable name like failed_constraints just to return it on the next line. Python allows you to build the list in memory and pass it straight out of the function via the return keyword.

How to think in these logical steps:
When you want to build a collection out of an existing loop, read the comprehension from middle to right, then left:

  1. Where am I looping? (for key, value in constraints.items())
  2. What is my filter condition? (if not value)
  3. What do I actually want to keep? (key)

It takes time to get used to, but it will click!

Ah, okay. That actually makes pretty good sense as to where the elements of the for loop are going, and even better, how to see it as the elements of a for loop and what each means. The loop is 3 lines and the comprehension reorganized them into 3-1-2 on a single line.

Now I even understand the solution(s) to the Number Pattern Generator. :sweat_smile:

Thank you, everyone.