Reading a json file and encoding problems
json, python, python-2.7
Solution
Assuming the JSON is formatted properly, the problem is that your code includes this check:
if k == "youtube":
for innerk, innerv in k.iteritems():
Given that you just asked for `k` to be `"youtube"` (an instance of `str` or `unicode`), it won't make sense to expect `k` to have an `iteritems` method.
I believe instead you are expecting the associated `dict` that would have come along with `k`, something like this:
if k == "youtube":
for innerk, innerv in value.iteritems():
I'm noticing from your JSON, though, that it looks like you should expect multiple `dict` variables to be loaded as the `list`-typed value for the case when `k == "youtube"`. In that case, you'll need to iterate over those elements first, asking for each one's `iteritems` separately:
if k == "youtube":
for each_dict in value:
for innerk, innerv in each_dict.iteritems():
or something along those lines. The final full code would be:
for item in j:
if item['trailers']:
e = item['trailers']
for k,value in e.iteritems():
if k == "youtube":
for each_dict in value:
for innerk, innerv in each_dict.iteritems():
if innerk == "source" :
print innerv
Aside from the first-order question, you should also take a look at the `dict` type's built-in method `get`, which allows you to safely get items from a dictionary and handle the case when they are missing gracefully. In your code, when you say `if item['trailers']:` this may not behave the way you expect.
First, if `trailers` is not a key to the dictionary, it will generate a `KeyError` instead of just skipping that conditional block. Secondly, if the value stored for the key value `trailers` evaluates to `False` in a `bool` context, the conditional block will also be skipped, even if you had wanted to handle it differently (for example, suppose that `None` is a sentinel value signaling that there is no data for `trailers` in that case, but it's due to a specific error that you want to log.
Meanwhile, if it's just an empty `dict` then that does mean you should simply skip the conditional block). This may not matter much in one-off data exploration, but in general it's good to become automatically conditioned to avoid these sorts of pitfalls, especially when the built-in types themselves make it very easy to handle things more gracefully.
Given all of this, a more Pythonic approach might be as follows:
for item in j:
y_tube = item.get('trailers', {}).get("youtube", [])
for each_dict in y_tube:
print each_dict.get("source", "Warning: no entry found for 'source'")
Problem
I would like to parse a JSON file and print `source` in this code fragment : ``` { "trailers": { "quicktime": [], "youtube": [ { "source": "mmNhzU6ySL8", "type": "Trailer", "name": "Trailer 1", "size": "HD" }, { "source": "CPTIgILtna8", "type": "Trailer", "name": "Trailer 2", "size": "Standard" } ], "id": 27205 }, ``` I wrote this code : ``` for item in j: if item['trailers']: e = item['trailers'] for k,value in e.iteritems(): if k == "youtube": for innerk, innerv in k.iteritems(): if innerk == "source" : print innerv ``` unfortunately I can't resolve this error : ``` for innerk, innerv in k.iteritems(): AttributeError: 'unicode' object has no attribute 'iteritems' ```