Last active
October 3, 2017 08:09
-
-
Save m0xb/045ae6e510893a225f623a505ec0c24b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [ | |
| { | |
| "id": "0001", | |
| "type": "donut", | |
| "name": "Cake", | |
| "ppu": 0.55, | |
| "batters": | |
| { | |
| "batter": | |
| [ | |
| { "id": "1001", "type": "Regular" }, | |
| { "id": "1002", "type": "Chocolate" }, | |
| { "id": "1003", "type": "Blueberry" }, | |
| { "id": "1004", "type": "Devil's Food" } | |
| ] | |
| }, | |
| "topping": | |
| [ | |
| { "id": "5001", "type": "None" }, | |
| { "id": "5002", "type": "Glazed" }, | |
| { "id": "5005", "type": "Sugar" }, | |
| { "id": "5007", "type": "Powdered Sugar" }, | |
| { "id": "5006", "type": "Chocolate with Sprinkles" }, | |
| { "id": "5003", "type": "Chocolate" }, | |
| { "id": "5004", "type": "Maple" } | |
| ] | |
| }, | |
| { | |
| "id": "0002", | |
| "type": "donut", | |
| "name": "Raised", | |
| "ppu": 0.55, | |
| "batters": | |
| { | |
| "batter": | |
| [ | |
| { "id": "1001", "type": "Regular" } | |
| ] | |
| }, | |
| "topping": | |
| [ | |
| { "id": "5001", "type": "None" }, | |
| { "id": "5002", "type": "Glazed" }, | |
| { "id": "5005", "type": "Sugar" }, | |
| { "id": "5003", "type": "Chocolate" }, | |
| { "id": "5004", "type": "Maple" } | |
| ] | |
| }, | |
| { | |
| "id": "0003", | |
| "type": "donut", | |
| "name": "Old Fashioned", | |
| "ppu": 0.55, | |
| "batters": | |
| { | |
| "batter": | |
| [ | |
| { "id": "1001", "type": "Regular" }, | |
| { "id": "1002", "type": "Chocolate" } | |
| ] | |
| }, | |
| "topping": | |
| [ | |
| { "id": "5001", "type": "None" }, | |
| { "id": "5002", "type": "Glazed" }, | |
| { "id": "5003", "type": "Chocolate" }, | |
| { "id": "5004", "type": "Maple" } | |
| ] | |
| } | |
| ] |
Author
#Task 1.1
task1_1 = [donut['id'] for donut in donutjson if donut['name'] == 'Raised'][0]
print(task1_1)
#Task 2.1
task2_1 = [donut['ppu'] for donut in donutjson if donut['name'] == 'Old Fashioned'][0]
print(task2_1)
#Task 3.1
print(len([donut['topping'] for donut in donutjson if donut['id'] == '0003'][0]))
#Task 4.1
print(len([donut['batters']['batter'] for donut in donutjson if donut['id'] == '0001'][0]))
#Task 5.1
print([[topping['type'] for topping in donut['topping'] if topping['id'] == '5003'] for donut in donutjson][0][0])
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the original expression and the result of evaluating it on the example in this gist:
Let's break it down. Work from the innermost sub-expression to the outermost.
The smallest valid sub-expression is still a bit unwieldy:
You can see that it returns a list of lists. Each list has exactly one element, the string
"Chocolate".The expression above is two list comprehensions. The inner one,
[t['type'] for t in d['topping'] if t['id'] == '5003']depends on the variabledwhich is bound to an element fromdonutsin the outer list comprehension. Sodrepresents a single donut object from the JSON. Givend(representing a donut), the inner list comprehension iterates over each topping, bound tot, in the donut (d['topping'], the JSON has the quirk of this property not being plural, but it's still a list), uses theifto filter out toppings that do not have theid5003, and generates a new list with thetypeof each topping that wasn't filtered.Note that we've basically got the answer already, but we need to clean it up, since it's a list of lists.
In this particular example, we could just append
[0][0]to the expression to access the first element of the first list:But, that's not good because we're making assumptions (in this case, that the first donut has the topping we want).
This doesn't work (suppose we were looking for 5005 instead of 5003:
So, we need to a filter to ensure there are no empty lists:
In the above,
mis bound to an element from the middle list comprehension, which is a list of topping types. Note that no elements get filtered out in the case for 5003, but that's okay, the point is to be safe:We still have a list of list of strings, when we just want a string. We know all the lists are the same, so let's get the first one. Again, we could append
[0]to the expression, but we want to avoid assumptions when possible.We pass our current expression to
enumeratewhich produces a list of tuples:Now, we can easily filter out all elements that aren't the first with another list comprehension:
Finally, we have a one-element list. In my solution, I made an assumption that it had at least one element, and just appended
[0]to the end:Which works in this case. But, would error if there were not toppings with
id5003. To make it not error out, I could do:To prove that the second one works for an invalid
idwhile the first one does not: