Python優雅的合併兩個Dict

2021-08-06 02:06:27 字數 4440 閱讀 1095

一行**合併兩個dict

假設有兩個dict x和y,合併成乙個新的dict,不改變 x和y的值,例如

x =

y =

期望得到乙個新的結果z,如果key相同,則y覆蓋x。期望的結果是

>>> z

在pep448中,有個新的語法可以實現,並且在python3.5中支援了該語法,合併**如下

z =

妥妥的一行**。 由於現在很多人還在用python2,對於python2和python3.0-python3.4的人來說,有乙個比較優雅的方法,但是需要兩行**。

z = x.copy()

z.update(y)

上面的方法,y都會覆蓋x裡的內容,所以最終結果b=3.

不使用python3.5如何一行完成了

如果您還沒有使用python 3.5,或者需要編寫向後相容的**,並且您希望在單個表示式中執行,則最有效的方法是將其放在乙個函式中:

def merge_two_dicts(x, y):

"""given two dicts, merge them into a new dict as a shallow copy."""

z = x.copy()

z.update(y)

returnz

然後一行**完成呼叫:

z = merge_two_dicts(x, y)

你也可以定義乙個函式,合併多個dict,例如

def merge_dicts(*dict_args):

"""given any number of dicts, shallow copy and merge into a new dict,

precedence goes to key value pairs in latter dicts.

"""result = {}

fordictionaryindict_args:

result.update(dictionary)

returnresult

然後可以這樣使用

z = merge_dicts(a, b, c, d, e, f, g)

所有這些裡面,相同的key,都是後面的覆蓋前面的。

一些不夠優雅的示範

items

有些人會使用這種方法:

z = dict(x.items() + y.items())

這其實就是在記憶體中建立兩個列表,再建立第三個列表,拷貝完成後,建立新的dict,刪除掉前三個列表。這個方法耗費效能,而且對於python3,這個無法成功執行,因為items()返回是個物件。

>>>c= dict(a.items() +b.items())

traceback (most recentcall last):

file "", line 1, in

typeerror: unsupported operand type(s)for+: 'dict_items' and 'dict_items'

你必須明確的把它強制轉換成list,z = dict(list(x.items()) + list(y.items())),這太浪費效能了。 另外,想以來於items()返回的list做並集的方法對於python3來說也會失敗,而且,並集的方法,導致了重複的key在取值時的不確定,所以,如果你對兩個dict合併有優先順序的要求,這個方法就徹底不合適了。

>>>x=

>>>y=

>>> dict(x.items() |y.items())

traceback (most recentcall last):

file "", line 1, in

typeerror: unhashable type: 'list'

這裡有乙個例子,其中y應該具有優先權,但是由於任意的集合順序,x的值被保留:

>>> x = >>> y = >>> dict(x.items() | y.items())

建構函式

也有人會這麼用

z = dict(x, **y)

這樣用很好,比前面的兩步的方法高效多了,但是可閱讀性差,不夠pythonic,如果當key不是字串的時候,python3中還是執行失敗

>>> c = dict(a, **b)

traceback (most recent call last):

file "", line 1,in<module>typeerror: keyword arguments must be strings

guido van rossum 大神說了:宣告dict({},)是非法的,因為畢竟是濫用機制。雖然這個方法比較hacker,但是太投機取巧了。

一些效能較差但是比較優雅的方法

下面這些方法,雖然效能差,但也比items方法好多了。並且支援優先順序。

python2.6中可以這樣

dict((k, v)fordindictsfork, vind.items())

import itertools

z = dict(itertools.chain(x.iteritems(), y.iteritems()))

效能測試

以下是在ubuntu 14.04上完成的,在python 2.7(系統python)中:

>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))0.5726828575134277

>>> min(timeit.repeat(lambda: ))1.163769006729126

>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(),y.iteritems()))))1.1614501476287842

>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))2.2345519065856934

在python3.5中

>>> min(timeit.repeat(lambda: ))0.4094954460160807

>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))0.7881555100320838

>>> min(timeit.repeat(lambda: ))1.4525277839857154

>>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items()))))2.3143140770262107

>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))3.2069112799945287

python將兩個list合併成乙個dict的方法

python將兩個list合併成乙個dict的方法 不使用內建函式,直接用 def run list2 1 2,3 4,5 list3 a b c d e dict i 0 length len list2 while i dict list2 i list3 i 這種方法也可以 dit dict ...

Python合併兩個列表的方法

瀏覽部落格看到乙個問題 如何合併兩個列表,今天就來 一下。方法一 最原始,最笨的方法,分別從兩個列表中取出所有的元素,再放入新列表中就ok了。示例 如下 list1 1,2,3 list2 4,5,6 list new for item in list1 for item in list2 prin...

合併兩個byte

byte sshead system.text.encoding.unicode.getbytes this is head byte sscontent system.text.encoding.unicode.getbytes this is content.sshead sscontent b...