我正在编写一个从JSON文件中提取数据的代码,下面是JSON文件:Google CDN
下面是JSON代码的一个例子:
{
"syncToken": "1677578581095",
"creationTime": "2023-02-28T02:03:01.095938",
"prefixes": [{
"ipv4Prefix": "34.80.0.0/15",
"service": "Google Cloud",
"scope": "asia-east1"
}, {
"ipv4Prefix": "34.137.0.0/16",
"service": "Google Cloud",
"scope": "asia-east1"
}, {
"ipv4Prefix": "35.185.128.0/19",
"service": "Google Cloud",
"scope": "asia-east1"
}, {
"ipv6Prefix": "2600:1900:40a0::/44",
"service": "Google Cloud",
"scope": "asia-south1"
},
我知道问题出在哪里,但不能解决这个网站上的解决方案的问题,并得到另一个错误的每一次。
这是我的密码
import json
f = open('cloud.json')
data = json.load(f)
array = []
for i in data['prefixes']:
array = [i['prefix'] for i in data['ipv4Prefix']]
f_path = (r"ip.txt")
with open (f_path ,'w') as d:
for lang in array:
d.write("{}\n".format(lang))
f.close()
基本上我只想提取ipv4地址,但有一些ipv6地址随机块,导致这个错误,所以我得到这样的关键错误:密钥错误:"ipv4前缀"
我知道为什么我会得到这个错误,所以我尝试删除整个条目与ipv6Prefix,所以我添加了这部分到我的代码:
if data[i]["prefixes"] == "ipv6Prefix":
data.pop(i)
对于这个,我得到TypeError:不可散列类型:"dict"对我来说是新的,我也试过这个,就像有人在另一个问题中指出的那样,但它不起作用。
del data[ipv6Prefix]
现在我的最终代码是这样的,并得到这个错误:TypeError:列表索引必须是整数或切片,而不是可以理解的字符串。
import json
f = open('cloud.json')
data = json.load(f)
array = []
for i in data['prefixes']:
if [i]["prefixes"] == ['ipv6Prefix']:
data.pop(i)
array = [i['prefix'] for i in data['ipv4Prefix']]
f_path = (r"ip.txt")
with open (f_path ,'w') as d:
for lang in array:
d.write("{}\n".format(lang))
f.close()
那么,我如何删除带有'ipv6Prefix'的条目,或者更确切地说,在我的for循环中忽略它们?
我找到了this问题,但答案根本不符合我的代码。
我的代码有什么问题?
我尝试了几种方法,如del
和dict.pop()
,但仍然出现错误。
2条答案
按热度按时间rdrgkggo1#
你有两个选择:Look Before You Leap or Easier to Ask Forgiveness than Permission。简而言之:
if
检查以确保ipv4Prefix
存在ipv4Prefix
存在,但捕获异常(本例中为KeyError
)下面的代码演示了这两种方法,但不包括写出结果。
使用哪种风格是主观的。Python有偏爱EAFP的名声,但是如果错误是正常操作的一部分,我更喜欢使用LYBL。在你的例子中,你知道有些对象 * 不 * 有
ipv4Prefix
,所以我认为LBYL在这里更合适。yhuiod9q2#
您可以跳过/忽略包含
ipv6Prefix
的前缀和if...continue
:只能将包含
ipv4Prefix
的前缀与 *if 'ipv4Prefix' in...
* 一起写入您可以更改
data
本身以省略包含ipv6Prefix
和list comprehension的前缀:您可以将包含
ipv4Prefix
的前缀列表另存为json.dump
的JSON:TypeError: list indices must be integers or slices, not str
*这可能是由于 *
if [i]["prefixes"] == ['ipv6Prefix']:
* 行;[i]
是一个list,其中只有一个项[i
,这是一个字典],所以 *[i]["prefixes"]
* 没有任何意义。您可以使用if 'ipv6Prefix' in i["prefixes"]
来代替,但是在该块中尝试完成的操作有更多问题[我将在下一节中解释]。.pop
方法只接受一个integer作为输入[必须是要从列表中删除的项的index],但是i
是data['prefixes']
中的一个 dictionary 的副本,因此如果试图执行 *.pop(i)
*,它将引发一个错误。您可以循环通过
enumerate
(data['prefixes'])
(而不是仅仅 *data['prefixes']
*)来跟踪与i
相关联的索引,但请记住,循环通过列表到pop
多个项目[来自同一列表]是 * 不 * 可取的。例如,如果您从列表[index=1]弹出第二个项目,则其后所有项的索引减1;因此,如果您接下来需要弹出列表中 * 原来 * 的第5项,enumerate
将告诉您它的索引是4,但在执行 *.pop(1)
* 之后它实际上变成了3...您 * 可以 * 如下所示反向循环遍历列表(但是我之前建议的列表理解方法不是更简单吗?)
顺便说一句,除了
reversed
,你也可以像data['prefixes'][::-1]
一样使用slicing,我只是认为使用这个函数更好的可读性,因为它使它所做的事情非常明显。TypeError: unhashable type: 'dict'
,这对我来说是新的 *i
是一个字典(如错误消息所述,它是不可散列的),因此不能像 *....data[i]...
* 那样用作键。可能来自 *
array = [i['prefix'] for i in data['ipv4Prefix']]
* 中的data['ipv4Prefix']
位,因为data
没有密钥ipv4Prefix
;***for i in data['prefixes']
*中的一些i
可能会,但是使用 *if 'ipv4Prefix' in i: del i
****没有意义,因为i
是正在循环通过的列表中的项的 * 副本 。您可以尝试使用
.remove
,如data['prefixes'].remove(i)
[而不是 *del i
*],但我不认为这是非常有效的。列表解析绝对是我在这种情况下的首选方法[也可能被认为是最“Python”的方法]。