读取json文件和编码问题

4m1*_*4j1 3 python json python-2.7

我想解析一个JSON文件并source在此代码片段中打印:

{
        "trailers": {
            "quicktime": [], 
            "youtube": [
                {
                    "source": "mmNhzU6ySL8", 
                    "type": "Trailer", 
                    "name": "Trailer 1", 
                    "size": "HD"
                }, 
                {
                    "source": "CPTIgILtna8", 
                    "type": "Trailer", 
                    "name": "Trailer 2", 
                    "size": "Standard"
                }
            ], 
            "id": 27205
        }, 
Run Code Online (Sandbox Code Playgroud)

我写了这段代码:

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
Run Code Online (Sandbox Code Playgroud)

不幸的是我无法解决此错误:

for innerk, innerv in k.iteritems():

AttributeError: 'unicode' object has no attribute 'iteritems'
Run Code Online (Sandbox Code Playgroud)

ely*_*ely 7

假设JSON格式正确,问题是您的代码包含此检查:

if k == "youtube":
    for innerk, innerv in k.iteritems():
Run Code Online (Sandbox Code Playgroud)

鉴于你刚才要求(或者k"youtube"一个实例),期望有一个方法是没有意义的.strunicodekiteritems

我相信你会期待与之相关的关联dict,k如下所示:

if k == "youtube":
    for innerk, innerv in value.iteritems():
Run Code Online (Sandbox Code Playgroud)

我注意到你的JSON,看起来你应该期望多个dict变量被加载为listcase的-typed值k == "youtube".在这种情况下,您需要首先迭代这些元素,分别要求每个元素iteritems:

if k == "youtube":
    for each_dict in value:
        for innerk, innerv in each_dict.iteritems():
Run Code Online (Sandbox Code Playgroud)

或类似的规定.最终的完整代码是:

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
Run Code Online (Sandbox Code Playgroud)

除了第一个问题之外,您还应该查看dict类型的内置方法get,它允许您安全地从字典中获取项目并在优雅地丢失时处理案例.在您的代码中,当您说if item['trailers']:这可能不像您期望的那样.

首先,如果trailers不是字典的关键字,它将生成一个KeyError而不是仅仅跳过该条件块.其次,如果为键值存储的值在上下文中trailers求值,则即使您想要以不同方式处理它,也会跳过条件块(例如,假设这是一个标记没有数据的标记值)在这种情况下,但这是由于您要记录的特定错误.FalseboolNonetrailers

同时,如果它只是一个空,dict那么这意味着你应该简单地跳过条件块).这在一次性数据探索中可能并不重要,但总的来说,自动调节以避免这些陷阱是很好的,特别是当内置类型本身使得更容易处理更优雅的事情时.

鉴于所有这些,更多的Pythonic方法可能如下:

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'")
Run Code Online (Sandbox Code Playgroud)