2016-06-18 27 views
4

でJSONファイルを解析しながら、このチュートリアルhttps://www.dataquest.io/blog/python-json-tutorial/は私が彼らのコードメモリの問題ijson

import ijson 

filename = "md_traffic.json" 
with open(filename, 'r') as f: 
    objects = ijson.items(f, 'meta.view.columns.item') 
    columns = list(objects) 

を実行したときにしかし私は、ファイルを待っているの10+分に実行しているよ、彼らが動作する600メガバイトのファイルを持っていますijsonに読み込まれると、これはどのように合理的になっているのか本当に混乱しています。解析するべきではありませんか?何か不足していますか?

+1

もし私がうまくいけば、そのような操作を避けることを目的としたイテレータを繰り返し実行するのにlist()を使用しますか? この例では、誤解を招く例があります。それはファイル全体ではなく、ファイルの一部だけに使用するべきです。 –

答えて

1

これは、ここで見つけるチュートリアルの直接コピー/ペーストのようになります。

https://www.dataquest.io/blog/python-json-tutorial/

それはそう長く取っている理由はijson.items関数の出力の周りlist()です。これにより、ファイル全体の解析が強制的に強制され、結果が返されます。ジェネレータであるijson.itemsを利用して、最初の結果がほぼ即座に戻すことができる。

import ijson 

filename = "md_traffic.json" 
with open(filename, 'r') as f: 
    for item in ijson.items(f, 'meta.view.columns.item'): 
     print(item) 
     break 

EDIT:チュートリアルの非常に次のステップでは、私は最初の項目を印刷含まれる理由である、print(columns[0])であります回答。また、質問がPython 2とPython 3のどちらであったかは明らかではないので、答えは両方で動作する構文を使用しています。

1

コードを実行しようとしましたが、25分後にプログラムを終了しました。だから10分、それは妥当な速さです。

+0

私は明白に10 +分後に私もそれを殺したことに気づいていない;) – boson

2

主な問題は、解析後に(個々の結果のみを1つの構造に集める)listを作成しているのではなく、ijsonが提供するデフォルトのpure-pythonバックエンドを使用していることです。

途方もなく速く使える他のバックエンドがあります。 ijson's homepageには、それらをインポートする方法が説明されています。 yajl2_cffiバックエンドは現時点では現在入手可能な中で最も速いですが、私は新しいyajl2_cバックエンドを作成しました(受け入れ中のpull requestがあります)。

yajl2_cffiバックエンドを使用しているノートパソコン(Intel(R)Core(TM)i7-5600U)では、コードは約1.5分で実行されます。 yajl2_cバックエンドを使用すると、〜10.5秒(Python 3)〜15秒(Python 2.7.12)で実行されます。

編集:@ lex-scarisbrickはもちろん、列名だけに興味がある場合は、ループからすぐに抜け出すこともできます。