web-dev-qa-db-ja.com

JSONの解析と検索

私はこのコードを持っています

import json
from pprint import pprint
json_data=open('bookmarks.json')
jdata = json.load(json_data)
pprint (jdata)
json_data.close()

u'uri': u'http:を検索するにはどうすればよいですか?

17
BKovac

なので json.loadsは単に辞書を返します。辞書に適用する演算子を使用できます。

>>> jdata = json.load('{"uri": "http:", "foo", "bar"}')
>>> 'uri' in jdata       # Check if 'uri' is in jdata's keys
True
>>> jdata['uri']         # Will return the value belonging to the key 'uri'
u'http:'

編集:データをループする方法に関するアイデアを与えるには、次の例を検討してください。

>>> import json
>>> jdata = json.loads(open ('bookmarks.json').read())
>>> for c in jdata['children'][0]['children']:
...     print 'Title: {}, URI: {}'.format(c.get('title', 'No title'),
                                          c.get('uri', 'No uri'))
...
Title: Recently Bookmarked, URI: place:folder=BOOKMARKS_MENU(...)
Title: Recent Tags, URI: place:sort=14&type=6&maxResults=10&queryType=1
Title: , URI: No uri
Title: Mozilla Firefox, URI: No uri

jdataデータ構造を調べると、希望どおりにナビゲートできます。既に持っているpprint呼び出しは、このための良い出発点です。

Edit2:別の試み。これにより、辞書のリストで言及したファイルが取得されます。これにより、ニーズに合わせて調整できるはずです。

>>> def build_structure(data, d=[]):
...     if 'children' in data:
...         for c in data['children']:
...             d.append({'title': c.get('title', 'No title'),
...                                      'uri': c.get('uri', None)})
...             build_structure(c, d)
...     return d
...
>>> pprint.pprint(build_structure(jdata))
[{'title': u'Bookmarks Menu', 'uri': None},
 {'title': u'Recently Bookmarked',
  'uri':   u'place:folder=BOOKMARKS_MENU&folder=UNFILED_BOOKMARKS&(...)'},
 {'title': u'Recent Tags',
  'uri':   u'place:sort=14&type=6&maxResults=10&queryType=1'},
 {'title': u'', 'uri': None},
 {'title': u'Mozilla Firefox', 'uri': None},
 {'title': u'Help and Tutorials',
  'uri':   u'http://www.mozilla.com/en-US/firefox/help/'},
 (...)
}]

それから"u'uri': u'http:' "、次のようにします。

for c in build_structure(jdata):
    if c['uri'].startswith('http:'):
        print 'Started with http'
22
jro

ObjectPath は、JSONおよびdictおよびリストのネストされた構造を照会する機能を提供するライブラリです。たとえば、$..fooを使用すると、「foo」と呼ばれるすべての属性を検索できます。

ドキュメントではコマンドラインインターフェイスに焦点を当てていますが、パッケージのPython internalsを使用してプログラムでクエリを実行できます。以下の例では、データをPythonデータ構造(dictsリスト)。JSONファイルまたは文字列で開始する場合は、 jsonのloadまたはloadsを使用するだけですmodule 最初。

import objectpath

data = [
    {'foo': 1, 'bar': 'a'},
    {'foo': 2, 'bar': 'b'},
    {'NoFooHere': 2, 'bar': 'c'},
    {'foo': 3, 'bar': 'd'},
]

tree_obj = objectpath.Tree(data)

Tuple(tree_obj.execute('$..foo'))
# returns: (1, 2, 3)

リストの3番目の項目など、「foo」属性のない要素をスキップしたことに注意してください。より複雑なクエリを実行することもできます。これにより、深くネストされた構造にObjectPathが便利になります(たとえば、xにyがありzを持つ場所を見つける:$.x.y.z)。詳細については、 documentation および tutorial を参照してください。

16
Scott H

Jroが提供するJSON dictにタイプミス(コロンの欠落)があるようです。

正しい構文は次のとおりです。jdata = json.load( '{"uri": "http:"、 "foo": "bar"}')

これは、コードで遊んでいるときにそれをクリアしました。

1
PythonPadawan

jsonpipe を使用して、出力だけが必要な場合(およびコマンドラインでより快適に)を使用できます。

cat bookmarks.json | jsonpipe |grep uri
0
number5

JSONなどの辞書を検索して出力する機能。 * made in python 3

探す:

def pretty_search(dict_or_list, key_to_search, search_for_first_only=False):
    """
    Give it a dict or a list of dicts and a dict key (to get values of),
    it will search through it and all containing dicts and arrays
    for all values of dict key you gave, and will return you set of them
    unless you wont specify search_for_first_only=True

    :param dict_or_list: 
    :param key_to_search: 
    :param search_for_first_only: 
    :return: 
    """
    search_result = set()
    if isinstance(dict_or_list, dict):
        for key in dict_or_list:
            key_value = dict_or_list[key]
            if key == key_to_search:
                if search_for_first_only:
                    return key_value
                else:
                    search_result.add(key_value)
            if isinstance(key_value, dict) or isinstance(key_value, list) or isinstance(key_value, set):
                _search_result = pretty_search(key_value, key_to_search, search_for_first_only)
                if _search_result and search_for_first_only:
                    return _search_result
                Elif _search_result:
                    for result in _search_result:
                        search_result.add(result)
    Elif isinstance(dict_or_list, list) or isinstance(dict_or_list, set):
        for element in dict_or_list:
            if isinstance(element, list) or isinstance(element, set) or isinstance(element, dict):
                _search_result = pretty_search(element, key_to_search, search_result)
                if _search_result and search_for_first_only:
                    return _search_result
                Elif _search_result:
                    for result in _search_result:
                        search_result.add(result)
    return search_result if search_result else None

印刷:

def pretty_print(dict_or_list, print_spaces=0):
    """
    Give it a dict key (to get values of),
    it will return you a pretty for print version
    of a dict or a list of dicts you gave.

    :param dict_or_list: 
    :param print_spaces: 
    :return: 
    """
    pretty_text = ""
    if isinstance(dict_or_list, dict):
        for key in dict_or_list:
            key_value = dict_or_list[key]
            if isinstance(key_value, dict):
                key_value = pretty_print(key_value, print_spaces + 1)
                pretty_text += "\t" * print_spaces + "{}:\n{}\n".format(key, key_value)
            Elif isinstance(key_value, list) or isinstance(key_value, set):
                pretty_text += "\t" * print_spaces + "{}:\n".format(key)
                for element in key_value:
                    if isinstance(element, dict) or isinstance(element, list) or isinstance(element, set):
                        pretty_text += pretty_print(element, print_spaces + 1)
                    else:
                        pretty_text += "\t" * (print_spaces + 1) + "{}\n".format(element)
            else:
                pretty_text += "\t" * print_spaces + "{}: {}\n".format(key, key_value)
    Elif isinstance(dict_or_list, list) or isinstance(dict_or_list, set):
        for element in dict_or_list:
            if isinstance(element, dict) or isinstance(element, list) or isinstance(element, set):
                pretty_text += pretty_print(element, print_spaces + 1)
            else:
                pretty_text += "\t" * print_spaces + "{}\n".format(element)
    else:
        pretty_text += str(dict_or_list)
    if print_spaces == 0:
        print(pretty_text)
    return pretty_text
0
Van4ozA