基于嵌套值在Json中检索值

时间:2016-10-02 03:41:31

标签: python json jq

我想检索给定特定id的投票,数据(对govtrack.us的赞美)存储在json中,我在python中编写并打算使用js

例如输入" Y000062"应该产生" Aye"

variable != null

在终端中,解决方案是cat /ccc/114/votes/2015/H384/data.json | egrep' Nay | Not Voting | Present | Yea | Aye | Y000062' | grep -B 1' Y000062' |头-1 但将其转发到python子流程似乎是一个笨重的解决方案。

注意:在Json中{}是一个Object,[]是一个数组

4 个答案:

答案 0 :(得分:0)

>>> d = {
...   "bill": {
...     "congress": 114,
...     "type": "hr"
...   },
...   "category": "passage",
...   "votes": {
...     "Aye": [
...       {
...         "display_name": "Abraham",
...         "id": "A000374",
...       },
...       {
...         "display_name": "Yarmuth",
...         "id": "Y000062",
...       }
...     ],
...     "Nay": [
...       {
...         "display_name": "Clyburn",
...     "id": "C000537",
...       },
...     ]}}
>>> 
>>> # store lookup value in variable to more easily change later
... lookup_value = 'Y000062'
>>> 
>>> # you're only concerned with the data in d['votes']
... for key, value in d['votes'].items():
...     # for each 'display_name' in the each vote type ('Aye' or 'Nay')
...     for element in value:
...         if element['id'] == lookup_value:
...             print(key)
... 
Aye
>>> 

答案 1 :(得分:0)

以下是实现此目的的示例函数:

The frontend server is running on port 3000!

其中def get_vote_cast_from_id(id): global my_json for name, nested_values in my_json['votes'].items(): if any(nested_value['id'] == id for nested_value in nested_values): return name else: return None get_vote_cast_from_id("A000374") # returns: "Aye" get_vote_cast_from_id("random_id") # returns: None 是存储my_json对象的全局变量。

答案 2 :(得分:0)

以下是使用jq的三种解决方案。如果一个人被限制投票一次,那么结果应该是相同的;否则,它们可能会有所不同,例如,个人被记录为Aye和Nay的投票。

第一个解决方案假设每个人最多投票一次。如果满足这个假设,那么它也是最有效的,因为它使用any/2,它具有“短路”语义:

$ jq  --arg id Y000062 '.votes
| if any( .Aye[]; select(.id == $id) ) then "Aye" 
elif any( .Nay[]; select(.id == $id) ) then "Nay"
else "none"
end' votes.json

下一个解决方案报告Ayes列表中每个人出现的“Aye”,如果Ayes列表中没有发现任何事件,则仅对Nays列表进行同样的操作:

$ jq  --arg id Y000062 '.votes
| ((.Aye[] | select(.id == $id) | "Aye") // 
   (.Nay[] | select(.id == $id) | "Nay")) ' votes.json

如果对个人在两个列表中出现的次数没有限制,则第三种解决方案可能是合适的。它首先构造[VOTE,ID]对的流,然后选择感兴趣的ID:

$ jq --arg id Y000062 '.votes
| ((.Nay[] | ["Nay", .id]),
   (.Aye[] | ["Aye", .id])))
| select(.[1] == $id)
| .[0]' votes.json

使用给定的输入(略微改变以使其成为有效的JSON),所有三种解决方案的输出是:

"Aye"

(您可以使用hjson等命令行工具将JSON-with-extra-commas转换为JSON。)

答案 3 :(得分:0)

以下是使用tostream

的jq解决方案
  .votes
| tostream
| select(length==2) as [$p,$v]
| select($v == $id)
| $p[0]

如果此过滤器位于filter.jq且示例数据位于data.json,则

jq -M --arg id Y000062 -f filter.jq data.json

产生

"Aye"