读取json文件和编码问题

时间:2013-12-17 20:10:53

标签: 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
        }, 

我写了这段代码:

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

遗憾的是我无法解决此错误:

for innerk, innerv in k.iteritems():

AttributeError: 'unicode' object has no attribute 'iteritems'

2 个答案:

答案 0 :(得分:7)

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

if k == "youtube":
    for innerk, innerv in k.iteritems():

鉴于您刚刚要求k"youtube"strunicode的实例),期望k没有意义拥有iteritems方法。

我相信你期待与dict一起出现的相关k,如下所示:

if k == "youtube":
    for innerk, innerv in value.iteritems():

我注意到你的JSON,看起来你应该期望多个dict变量作为list的{​​{1}}类型的值加载k == "youtube"。在这种情况下,您需要首先迭代这些元素,分别要求每个元素iteritems

if k == "youtube":
    for each_dict in value:
        for innerk, innerv in each_dict.iteritems():

或类似的东西。最终的完整代码是:

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

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

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

同时,如果它只是一个空的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'")

答案 1 :(得分:2)

看看这一行:

for k,value in e.iteritems()

很明显,k是一个键(在你的情况下是一个unicode字符串)。你清楚地知道这一点,你对if k == "youtube"进行了比较 Unicode字符串没有iteritems()方法。

我感觉你正在寻找的是:

for k,value in e.iteritems()
    for innerk,innerv in value.iteritems():
        # do stuff