在某些情況下,比較兩個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,然后進行安裝](https://pypi.python.org/pypi/json_tools%EF%BC%8C%E7%84%B6%E5%90%8E%E8%BF%9B%E8%A1%8C%E5%AE%89%E8%A3%85)
## 比較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
~~~
具體這個模塊如何使用,請看官到我做過的一個小項目中看看:[https://github.com/qiwsir/json-diff](https://github.com/qiwsir/json-diff)
- 第零部分 獨上高樓,望盡天涯路
- 嘮叨一些關于Python的事情
- 為什么要開設本欄目
- 第一部分 積小流,至江海
- Python環境安裝
- 集成開發環境(IDE)
- 數的類型和四則運算
- 啰嗦的除法
- 開始真正編程
- 初識永遠強大的函數
- 玩轉字符串(1):基本概念、字符轉義、字符串連接、變量與字符串關系
- 玩轉字符串(2)
- 玩轉字符串(3)
- 眼花繚亂的運算符
- 從if開始語句的征程
- 一個免費的實驗室
- 有容乃大的list(1)
- 有容乃大的list(2)
- 有容乃大的list(3)
- 有容乃大的list(4)
- list和str比較
- 畫圈還不簡單嗎
- 再深點,更懂list
- 字典,你還記得嗎?
- 字典的操作方法
- 有點簡約的元組
- 一二三,集合了
- 集合的關系
- Python數據類型總結
- 深入變量和引用對象
- 賦值,簡單也不簡單
- 坑爹的字符編碼
- 做一個小游戲
- 不要紅頭文件(1): open, write, close
- 不要紅頭文件(2): os.stat, closed, mode, read, readlines, readline
- 第二部分 窮千里目,上一層樓
- 正規地說一句話
- print能干的事情
- 從格式化表達式到方法
- 復習if語句
- 用while來循環
- 難以想象的for
- 關于循環的小伎倆
- 讓人歡喜讓人憂的迭代
- 大話題小函數(1)
- 大話題小函數(2)
- python文檔
- 重回函數
- 變量和參數
- 總結參數的傳遞
- 傳說中的函數條規
- 關于類的基本認識
- 編寫類之一創建實例
- 編寫類之二方法
- 編寫類之三子類
- 編寫類之四再論繼承
- 命名空間
- 類的細節
- Import 模塊
- 模塊的加載
- 私有和專有
- 折騰一下目錄: os.path.<attribute>
- 第三部分 昨夜西風,亭臺誰登
- 網站的結構:網站組成、MySQL數據庫的安裝和配置、MySQL的運行
- 通過Python連接數據庫:安裝python-MySQLdb,連接MySQL
- 用Pyton操作數據庫(1):建立連接和游標,并insert and commit
- 用Python操作數據庫(2)
- 用Python操作數據庫(3)
- python開發框架:框架介紹、Tornado安裝
- Hello,第一個網頁分析:tornado網站的基本結構剖析:improt模塊、RequestHandler, HTTPServer, Application, IOLoop
- 實例分析get和post:get()通過URL得到數據和post()通過get_argument()獲取數據
- 問候世界:利用GAE建立tornado框架網站
- 使用表單和模板:tornado模板self.render和模板變量傳遞
- 模板中的語法:tornado模板中的for,if,set等語法
- 靜態文件以及一個項目框架
- 模板轉義
- 第四部分 暮然回首,燈火闌珊處
- requests庫
- 比較json/dictionary的庫
- defaultdict 模塊和 namedtuple 模塊
- 第五部分 Python備忘錄
- 基本的(字面量)值
- 運算符
- 常用的內建函數
- 擴展閱讀(來自網絡文章)
- 人生苦短,我用Python