我正在学习Python,并试图将GitHub问题转换为可读的形式。使用“如何将JSON转换为CSV?”,我想到了这个:
import json
import csv
f = open('issues.json')
data = json.load(f)
f.close()
f = open("issues.csv", "wb+")
csv_file = csv.writer(f)
csv_file.writerow(["gravatar_id", "position", "number", "votes", "created_at", "comments", "body", "title", "updated_at", "html_url", "user", "labels", "state"])
for item in data:
csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])
”问题。json”是包含我的GitHub问题的json文件。当我试着运行它时,我得到
File "foo.py", line 14, in <module>
csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])
TypeError: string indices must be integers
我错过了什么?哪些是“字符串索引”?我敢肯定,一旦我得到这个工作,我将有更多的问题,但现在,我只是喜欢这个工作!
当我把for语句调整为简单
for item in data:
print item
我得到的是…“问题”——所以我做错了一些更基本的事情。以下是我的JSON内容:
{"issues": [{"gravatar_id": "44230311a3dcd684b6c5f81bf2ec9f60", "position": 2.0, "number": 263, "votes": 0, "created_at": "2010/09/17 16:06:50 -0700", "comments": 11, "body": "Add missing paging (Older>>) links...
当我打印数据时,它看起来很奇怪:
{u'issues': [{u'body': u'Add missing paging (Older>>) lin...
Slice符号str[a:b]的TypeError
简短的回答
在str[a:b]的两个索引a和b之间使用冒号,而不是逗号:
my_string[0,5] # wrong ❌
my_string[0:5] # correct ✅
长回答
当使用字符串和切片符号(一种常见的序列操作)时,可能会引发TypeError,指出索引必须是整数,即使它们显然是整数。
例子
>>> my_string = "Hello, World!"
>>> my_string[0,5]
TypeError: string indices must be integers
显然我们把两个整数作为下标传递给了切片符号,对吧?那么问题是什么呢?
这个错误会让人非常沮丧——尤其是在刚开始学习Python的时候——因为错误信息会有一点误导。
解释
当调用my_string[0,5]时,我们隐式地将两个整数的元组传递给slice符号。0,5的值与(0,5)的值相同——即使没有括号。为什么不过?
一个尾随逗号,实际上足以让Python解释器作为元组来求值:
>>> my_variable = 0,
>>> type(my_variable)
<class 'tuple'>
所以这次我们明确地做了:
>>> my_string = "Hello, World!"
>>> my_tuple = 0, 5
>>> my_string[my_tuple]
TypeError: string indices must be integers
现在,至少错误消息是有意义的。
解决方案
我们需要用冒号替换逗号:来正确地分隔两个整数,而不是将它们解释为元组:
>>> my_string = "Hello, World!"
>>> my_string[0:5]
'hello'
更清晰、更有帮助的错误消息应该是这样的:
TypeError: string indices must be integers not tuple
^^^^^
(actual type here)
一个好的错误消息应该直接告诉用户他们做错了什么!有了这些信息,找到根本原因并解决问题就容易得多了——你也不必来这里了。
因此,下次当您发现自己有责任编写错误描述消息时,请提醒自己这个示例并将原因(或其他有用的信息)添加到错误消息中!帮助别人(甚至是你未来的自己)理解哪里出了问题。
经验教训
切片表示法使用冒号:分隔它的索引(和步长范围,即str[从:到:步长])
元组由逗号定义(即t = 1,)
向错误消息中添加一些信息,以便用户了解出错的地方
如何读取这个JSON的第一个元素?
当文件像这样显示时
for i in data[1]:
print("Testing"+i['LocalObservationDateTime'])
这对我没用。
下面是JSON文件
[
{
"LocalObservationDateTime":"2022-09-15T19:05:00+02:00",
"EpochTime":1663261500,
"WeatherText":"Mostly cloudy",
"WeatherIcon":6,
"HasPrecipitation":false,
"PrecipitationType":"None",
"IsDayTime":true,
"Temperature":{
"Metric":{
"Value":11.4,
"Unit":"C",
"UnitType":17
},
"Imperial":{
"Value":52.0,
"Unit":"F",
"UnitType":18
}
},
"RealFeelTemperature":{
"Metric":{
"Value":8.4,
"Unit":"C",
"UnitType":17,
"Phrase":"Chilly"
}
}
},
{
"LocalObservationDateTime":"2022-09-16T19:05:00+02:00",
"EpochTime":1663261500,
"WeatherText":"Mostly cloudy",
"WeatherIcon":6,
"HasPrecipitation":false,
"PrecipitationType":"None",
"IsDayTime":true,
"Temperature":{
"Metric":{
"Value":11.4,
"Unit":"C",
"UnitType":17
},
"Imperial":{
"Value":52.0,
"Unit":"F",
"UnitType":18
}
},
"RealFeelTemperature":{
"Metric":{
"Value":8.4,
"Unit":"C",
"UnitType":17,
"Phrase":"Chilly"
}
}
}
]