Python 读取json文件和编码问题

Python 读取json文件和编码问题,python,json,python-2.7,Python,Json,Python 2.7,我想解析一个JSON文件,并在此代码片段中打印source: { "trailers": { "quicktime": [], "youtube": [ { "source": "mmNhzU6ySL8", "type": "Trailer", "name": "Trailer

我想解析一个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'

假设JSON格式正确,问题在于您的代码包含以下检查:

if k == "youtube":
    for innerk, innerv in k.iteritems():
考虑到您刚刚要求
k
成为
“youtube”
(一个
str
unicode
的实例),期望
k
拥有
iteritems
方法是没有意义的

相反,我相信您期望的是与
k
相关的
dict
,类似于:

if k == "youtube":
    for innerk, innerv in value.iteritems():
不过,我从您的JSON中注意到,对于
k==“youtube”
的情况,您应该期望将多个
dict
变量作为
列表
类型的值加载。在这种情况下,您需要首先迭代这些元素,分别请求每个元素的
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
type的内置方法
get
,它允许您安全地从字典中获取项目,并在项目丢失时优雅地处理。在您的代码中,当您说
if item['trailes']时:
这可能与您期望的行为方式不同

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

同时,如果它只是一个空的
dict
,那么这就意味着您应该跳过条件块)。这在一次性的数据探索中可能没什么大不了的,但一般来说,自动适应以避免这些陷阱是很好的,特别是当内置类型本身使处理事情变得更加优雅时

考虑到所有这些因素,一种更具python风格的方法可能如下所示:

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'")
请看这一行:

for k,value in e.iteritems()
很明显,
k
是一个键(在您的例子中是一个unicode字符串)。如果k==“youtube”,通过对
的比较,您可以清楚地知道这一点
Unicode字符串没有
iteritems()
方法

我觉得你在找的是:

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

我发现:
AttributeError:'list'对象没有属性“iteritems”
,我正在尝试修复它。这就是我的中间更新所涵盖的内容。请注意
“youtube”的JSON
是一个包含两个字典的
列表
。它不仅仅是一个字典。因此
将是一个
列表
。这意味着您需要进一步迭代那些
列表
元素(在我的答案中,我为每个值写了“
”)只有这样,您才能最终执行最内部的循环来打印存储在键
“source”
中的数据。您尝试过python库吗?