python比較json/dictionary的庫

hiekay發表於2019-01-16

在某些情況下,比較兩個json/dictionary,或許這樣就可以實現:

>>> a
{`a`: 1, `b`: 2}
>>> b
{`a`: 2, `c`: 2}
>>> cmp(a,b)        #-1或者1,代表兩個dict不一樣
-1
>>> c=a.copy()
>>> c
{`a`: 1, `b`: 2}
>>> cmp(a,c)       #兩者相同
0

但是,這隻能比較兩個是不是一樣,不能深入各處哪裡不一樣的比較結果。

有這樣一個庫,就能解決這個問題,它就是json_tools

安裝

方法1:

>>> pip install json_tools

或者

>>> easy_install json_tools

方法2:到這裡下載原始碼:https://pypi.python.org/pypi/json_tools,然後進行安裝

比較json

首先看看都有哪些屬性或者方法,用萬能的實驗室來看:

>>> import json_tools
>>> dir(json_tools)

[`builtins`, `doc`, `file`, `loader`, `name`, `package`, `path`, `_patch_main`, `_printer_main`, `diff`, `patch`, `path`, `print_function`, `print_json`, `print_style`, `printer`]

從上面的結果中,可以看到json_tools的各種屬性和方法。

我在一個專案中使用了diff,下面演示一下使用過程

>>> a
{`a`: 1, `b`: 2}
>>> b
{`a`: 2, `c`: 2}
>>> json_tools.diff(a,b)
[{`prev`: 1, `value`: 2, `replace`: `/a`}, {`prev`: 2, `remove`: `/b`}, {`add`: `/c`, `value`: 2}]

上面這個比較是比較簡單的,顯示的是b相對於a的變化,特別注意,如果是b相對a,就要這樣寫:json_tools.diff(a,b),如果是json_tools.diff(b,a),會跟上面有所不同,請看結果:

>>> json_tools.diff(b,a)
[{`prev`: 2, `value`: 1, `replace`: `/a`}, {`prev`: 2, `remove`: `/c`}, {`add`: `/b`, `value`: 2}]

json_tools(a,b),即b相對a發生的變化為例進行說明。

  • b和a都有鍵`a`,但是b相對a,鍵`a`的值發生了變化,由原來的1,變為了2。所以在比較結果的list中,有一個元素反應了這個結果{`prev`: 1, `value`: 2, `replace`: `/a`},其中,replace表示發生變化的鍵,value表示變化後即當前該鍵的值,prev表示該鍵此前的值。
  • b中的`c`相對與a,是新增的鍵。於是比較結果中這樣反應出來:{`add`: `/c`, `value`: 2}
  • b相對於a沒有`b`這個鍵,也就是在b中將其刪除了,於是比較結果中這樣來顯示:{`prev`: 2, `remove`: `/c`}

通過上述結果,就顯示出來的詳細的比較結果,不僅如此,還能對多層巢狀的json進行比較。例如:

>>> a={"a":{"aa":{"aaa":333,"aaa2":3332},"b":22}}
>>> b={"a":{"aa":{"aaa":334,"bbb":339},"b":22}}
>>> json_tools.diff(a,b)
[{`prev`: 3332, `remove`: `/a/aa/aaa2`}, {`prev`: 333, `value`: 334, `replace`: `/a/aa/aaa`}, {`add`: `/a/aa/bbb`, `value`: 339}]

這裡就顯明瞭發生變化的key的巢狀關係。比如`/a/aa/aaa2`,就表示{"a":{"aa":{"aaa2":...}}}的值發生了變化。

這裡有了一個key的巢狀字串,在真實的使用中,有時候需要將字串轉為json的格式,即{`prev`: 3332, `remove`: `/a/aa/aaa2`}轉化為{"a":{"aa":{"aaa2":3332}}}

將字串組裝成json格式

首先,回答前面的問題,可以自己寫一個函式,實現那種組裝。

但是,我是懶惰地程式設計師,我更喜歡python的原因就是它允許我懶惰。

from itertools import izip


相關文章