Python和JSON - TypeError列表索引必须是整数而不是字符串

33

我正在学习使用Python和API(具体来说,是这个世界杯API:http://www.kimonolabs.com/worldcup/explorer

JSON数据看起来像这样:

[
  {
    "firstName": "Nicolas Alexis Julio",
    "lastName": "N'Koulou N'Doubena",
    "nickname": "N. N'Koulou",
    "assists": 0,
    "clubId": "5AF524A1-830C-4D75-8C54-2D0BA1F9BE33",
    "teamId": "DF25ABB8-37EB-4C2A-8B6C-BDA53BF5A74D",
    "id": "D9AD1E6D-4253-4B88-BB78-0F43E02AF016",
    "type": "Player"
  },

 {
    "firstName": "Alexandre Dimitri",
    "lastName": "Song-Billong",
    "nickname": "A. Song",
    "clubId": "35BCEEAF-37D3-4685-83C4-DDCA504E0653",
    "teamId": "DF25ABB8-37EB-4C2A-8B6C-BDA53BF5A74D",
    "id": "A84540B7-37B6-416F-8C4D-8EAD55D113D9",
    "type": "Player"
  },
   ]

我只是试图打印出这个API中所有的firstName。这是我拥有的:

import urllib2
import json

url = "http://worldcup.kimonolabs.com/api/players?apikey=xxx"
json_obj = urllib2.urlopen(url).read
readable_json = json.dumps(json_obj)
playerstuff = readable_json['firstName']
for i in playerstuff:
    print i['firstName']

但是当我运行它时,出现错误"...line 8, in ...TypeError: list indices must be integers, not str"

我已经寻找解决方法,但好像只找到更深入的API问题,并且我还没有完全理解这些内容,所以任何帮助或解释我需要做什么都将不胜感激。谢谢!


1
只是一些常见的 Python 智慧 - requests 库 http://docs.python-requests.org/en/latest/ 通常比使用 urllib2 更好。 - Josh Smeaton
我会查看一下,谢谢! - user3718365
我能否不使用URL,而是读取类似于以下的内容:@app.route('/test', methods=['GET','POST']) def foo(): json_obj = request.json readable_json = json.loads(json_obj) for i in readable_json: print i['firstName'] 如果我尝试相同的操作,会出现TypeError: expected string or buffer。 - Sushivam
3个回答

35

我解决了变化

readable_json['firstName']

需要翻译的内容:

by

readable_json[0]['firstName']

hi = json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])ji = json.loads(hi), ji[0]["foo"] 最近的调用最后一行出现了错误: TypeError: 字符串索引必须是整数。 - ravi.zombie

33
首先,你应该使用json.loads而不是json.dumpsloads将JSON源文本转换为Python值,而dumps则相反。
在解决了这个问题后,基于你提供的JSON代码片段,readable_json将会是一个列表,因此readable_json ['firstName']是没有意义的。 获取列表中每个元素的'firstName'字段的正确方法是消除playerstuff = readable_json ['firstName']行,并将for i in playerstuff:更改为for i in readable_json:

啊哈!谢谢你的解释,这很有用。现在,为了更贪心一些,我该如何在名字旁边加上空格打印“lastName”呢?如果你有任何关于Python和API的教程推荐(从简单开始),我全耳朵倾听!感谢你的帮助! - user3718365
@user3718365:print i['firstName'], i['lastName'] - jwodder
谢谢!最后一个问题可以让我继续前进:如果我想列出所有可能的键(例如:firstName、lastName、age等),以便用户可以键入他们想查看的内容,我该如何返回一个键列表(这是否是正确的术语)?此外,我是 StackOverflow 的新手,所以如果我不应该在问题上添加问题,请见谅。 - user3718365
@user3718365:你不应该在问题上添加问题,但你的第一个额外问题很琐碎,而我心情还算不错。获取键列表的最简单方法是readable_json[0].keys(),但这假定列表的每个元素都具有相同的键集,这并不总是正确的。 - jwodder
readable_json = json.loads(json_obj)[0] 的缺点是什么? - Andreas Yankopolus

6
你可以把你的代码简化为:
url = "http://worldcup.kimonolabs.com/api/players?apikey=xxx"
json_obj = urllib2.urlopen(url).read
player_json_list = json.loads(json_obj)
for player in readable_json_list:
    print player['firstName']

你试图使用字典语法访问列表元素。相当于:
foo = [1, 2, 3, 4]
foo["1"]

当你拥有字典列表并需要保持嵌套顺序时,可能会感到困惑。


谢谢这个,帮了大忙。非常感激。 - user3718365

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接