【问题标题】:Filter Newline Delimited JSON过滤换行分隔的 JSON
【发布时间】:2018-04-03 21:24:03
【问题描述】:

我正在尝试从通过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'}

代码:

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 解释器中时,在每个字典之间添加括号和逗号,它会返回正确的输出。

代码

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 那样工作。 (我以前从未遇到过这个问题,所以任何见解都会有所帮助。)

【问题讨论】:

  • 在第一个示例中,test_data 在末尾而不是开头包含 ]
  • 已编辑(test_data 没有括号),谢谢指出
  • 你能把你的my_data发一下吗?
  • @bruntime,添加了“修复”算法。但是您能否将print my_data 的输出添加到您的问题中?
  • 已添加my_data 的输出以进行更多说明

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


【解决方案1】:

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

您可以为此使用 RegEx:

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

正则表达式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}]

编辑

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

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

【讨论】:

  • 我已经测试了这段代码,但它并没有像我预期的那样工作。 Python没有打印[{u'color': u'orange', u'mykey': 5678}, {u'color': u'yellow', u'mykey': 5678}],而是添加了括号,因此数据看起来像这样,而不是({u'color': u'orange', u'mykey': 5678},)({u'color': u'yellow', u'mykey': 5678},)
  • 它是一个元组,您可以添加list 将其转换为列表,即list(filter(...)),它会给您:[{u'color': u'orange', u'mykey': 5678}, {u'color': u'yellow', u'mykey': 5678}]
  • 你一定做错了,因为我得到了正确的输出,python 2.x:repl.it/NIAJ/1,python 3.x:repl.it/NIAM/2
  • 你是对的。我刚刚注意到我使用的是self.response.write 而不是printprint 工作正常,但 self.response.write 返回 [{u'color': u'red', u'mykey': 1234}, {u'color': u'orange', u'mykey': 5678}, {u'color': u'yellow', u'mykey': 5678}][{u'color': u'red', u'mykey': 1234}, {u'color': u'orange', u'mykey': 5678}, {u'color': u'yellow', u'mykey': 5678}]。我会相应地编辑我的问题,因为我没有意识到会有两个不同的输出。
  • @bruntime 您还需要在使用self.response.write 时写:json.dumps()。所以,self.response.write(json.dumps(test_data)) 会起作用
【解决方案2】:

假设:

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 中的工作程序。

【讨论】:

  • 这个解决方案对我不起作用。我收到错误消息:ValueError: Expecting property name: line 1 column 2 (char 1).
  • @bruntime,您能解释一下程序中的第 1 行是什么吗?还添加了这段代码的直播节目。
  • 我只是在 PyCharm 中使用 Python 2.7 测试这个解决方案。
  • 感谢您提供 2 个工作版本。我会研究为什么它不适合我。
  • 我无法让此解决方案为我工作,但我已将您的回答标记为有帮助。
猜你喜欢
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 2018-12-20
  • 2015-05-12
  • 2015-07-10
  • 1970-01-01
相关资源
最近更新 更多