过滤换行符分隔的JSON

时间:2017-10-23 10:46:21

标签: python json python-2.7 google-app-engine

我正在尝试从json.dumps返回的词典列表中进行过滤。但是,由于它是换行符分隔的JSON(字典不用逗号分隔),我收到错误。

>>>> print my_data
>>>> {u'mykey': 1234, u'color': u'red'} {u'mykey': 5678, u'color': u'orange'} {u'mykey': 5678, u'color': u'yellow'}

CODE:

key = 5678

test_data = json.dumps(my_data)
self.response.write(test_data)
  # test_data outputs {"mykey": 1234, "color": "red"} {"mykey": 5678, "color": "orange"} {"mykey": 5678, "color": "yellow"}

test = filter(lambda thedata: thedata['mykey'] == key, test_data)
print test

错误:

  

test = filter(lambda thedata:thedata ['mykey'] == key,test_data)

     

TypeError:'NoneType'对象不可迭代

当我将相同的数据复制到Python解释器中时,在每个字典之间添加括号和逗号,它会返回正确的输出。

CODE

key = 5678

test_data = [
  {"mykey": 1234, "color": "red"},
  {"mykey": 5678, "color": "orange"},
  {"mykey": 5678, "color": "yellow"}]

test = filter(lambda thedata: thedata['mykey'] == key, test_data)
print test

输出:

  

[{'color':'orange','mykey':5678},{'color':'yellow','mykey':5678}]

如何修复我的代码或JSON输出以便我可以正确过滤?

编辑(更正):

我正在寻找使用self.response.write而不是print的解决方案。

在使用@Ashish Ranjan的答案时,我注意到print的输出与self.response.write不同。建议的解决方案应使用self.response.write

test = filter(lambda thedata: thedata['mykey'] == key, test_data)
self.response.write(test)

使用@Ashish解决方案的当前输出是:

硬编码数据:

my_data = "{u'mykey': 1234, u'color': u'red'} {u'mykey': 5678, u'color': u'orange'} {u'mykey': 5678, u'color': u'yellow'}"
test_data = ast.literal_eval("[" + re.sub(r'({[^\}]*})\s', r'\1,' , my_data) + "]")
test = filter(lambda thedata: thedata['mykey'] == 5678, test_data)
self.response.write(test_data)
  

[{u'mykey':1234,u'color':u'red'},{u'mykey':5678,u'color':u'orange'},{u'mykey':5678, u'color':u'yellow'}] [{u'mykey':1234,u'color':u'red'},{u'mykey':5678,u'color':u'orange'}, {u'mykey':5678,u'color':u'yellow'}]

来自JSON对象

dumped_data = json.dumps(my_data)
test_data = ast.literal_eval("[" + re.sub(r'({[^\}]*})\s', r'\1,' , dumped_data) + "]")
test = filter(lambda thedata: thedata['mykey'] == 5678, test_data)
self.response.write(test_data)
  

({u'color':u'orange',u'mykey':5678},)({u'color':u'yellow',u'mykey':5678},)

注意:即使使用print进行测试,JSON数据也无法正确输出结果。相反,它在单独的行上打印每个数据:

  

[{u'color':u'orange',u'mykey':5678}]

     

[{u'color':u'yellow',u'mykey':5678}]

所有这些结果都不正确。我不明白为什么self.response.write不像print那样工作。 (我之前从未遇到过这个问题,因此任何见解都会有所帮助。)

2 个答案:

答案 0 :(得分:1)

假设:

s = r'{"mykey": 1234, "color": "red"} {"mykey": 5678, "color": "orange"} {"mykey": 5678, "color": "yellow"}'

您可以字符串修复为有效的json对象,如下所示:

delim = "}"
jsons =  [json.loads(token.strip() + delim) for token in s.split(delim) if token]

然后解析它:

key = 5678
test = filter(lambda thedata: thedata['mykey'] == key, jsons)

以下是Python2Python3中的工作程序。

答案 1 :(得分:1)

在使用my_data之前,您可以将filter转换为有效的python列表/词典。

您可以使用RegEx:

import re
import ast
test_data = ast.literal_eval("[" + re.sub(r'({[^\}]*})\s', r'\1,' , my_data) + "]")

RegEx demo

<强>输出

>>> test_data
[{u'mykey': 1234, u'color': u'red'},{u'mykey': 5678, u'color': u'orange'},{u'mykey': 5678, u'color': u'yellow'}]
>>> test_data = filter(lambda thedata: thedata['mykey'] == 5678, test_data)
>>> test_data
[{u'color': u'orange', u'mykey': 5678}, {u'color': u'yellow', u'mykey': 5678}]

修改

使用json.dumps()时,您需要使用self.response.write。所以,这将有效:

self.response.write(json.dumps(test_data))