Python:用同一个键合并两个字典的最优雅的方式
Python: Most elegant way to merge two dictionaries with the same key
我正在研究基因组规模的模型,并试图创建适合两种最佳通量条件的基本培养基。我得到了两本字典,其中包含所需的媒体组件,如下所示:
EX_C00001_ext_b 1.132993
EX_C00011_ext_b 1.359592
EX_E1_ext_b 16.000000
EX_C00034_ext_b 0.000088
EX_C00244_ext_b 0.259407
EX_C00182N_cyt_b 0.006079
EX_C00009_ext_b 0.020942
EX_C01330_ext_b 0.000110
EX_C00080_ext_b 0.258331
EX_C00001_ext_b 0.780699
EX_C14819_ext_b 0.000197
EX_C00059_ext_b 0.005162
EX_C00011_ext_b 1.198398
EX_C14818_ext_b 0.000217
EX_C00305_ext_b 0.000802
EX_C00038_ext_b 0.000088
EX_C00070_ext_b 0.000088
EX_C06232_ext_b 0.000088
EX_C00076_ext_b 0.000131
EX_C00238_ext_b 0.004925
EX_E1_ext_b 16.000000
EX_C00175_ext_b 0.000094
我想合并两个词典,以最优雅的方式为每个代谢物选择最高值,并且无论词典大小如何,它都应该可用。
它应该给我以下结果:
EX_C00034_ext_b 0.000088
EX_C00244_ext_b 0.259407
EX_C00182N_cyt_b 0.006079
EX_C00009_ext_b 0.020942
EX_C01330_ext_b 0.000110
EX_C00080_ext_b 0.258331
EX_C00001_ext_b 1.132993
EX_C14819_ext_b 0.000197
EX_C00059_ext_b 0.005162
EX_C00011_ext_b 1.359592
EX_C14818_ext_b 0.000217
EX_C00305_ext_b 0.000802
EX_C00038_ext_b 0.000088
EX_C00070_ext_b 0.000088
EX_C06232_ext_b 0.000088
EX_C00076_ext_b 0.000131
EX_C00238_ext_b 0.004925
EX_E1_ext_b 16.000000
EX_C00175_ext_b 0.000094
以下是供您使用的示例字典。
{'EX_C00034_ext_b': 8.757888959017035e-05, 'EX_C00244_ext_b': 0.2594073529471562, 'EX_C00182N_cyt_b': 0.006078784247428623, 'EX_C00009_ext_b': 0.02094224214212716, 'EX_C01330_ext_b': 0.00010954587179767827, 'EX_C00080_ext_b': 0.2583314448433369, 'EX_C00001_ext_b': 0.7806992563484072, 'EX_C14819_ext_b': 0.00019712476138777617, 'EX_C00059_ext_b': 0.005162038491279668, 'EX_C00011_ext_b': 1.1983981620820985, 'EX_C14818_ext_b': 0.00021724189246195394, 'EX_C00305_ext_b': 0.0008020492051022175, 'EX_C00038_ext_b': 8.757888959017035e-05, 'EX_C00070_ext_b': 8.757888959017036e-05, 'EX_C06232_ext_b': 8.757888959017035e-05, 'EX_C00076_ext_b': 0.00013122381476546977, 'EX_C00238_ext_b': 0.0049252286422986884, 'EX_E1_ext_b': 16.000000000000245, 'EX_C00175_ext_b': 9.42845999482296e-05}
{'EX_C00001_ext_b': 1.1329932376320115, 'EX_C00011_ext_b': 1.3595918851584152, 'EX_E1_ext_b': 16.000000000000387}
请注意,我不知道哪个字典中有更高的值。
编辑
正如您从我的示例中看到的,即使两个字典都包含相同的键,但并非所有键都在两个字典中。所以我无法遍历这些键,因为我不知道我是否跳过了其中一个键。
我想你可以先从我需要合并的所有字典中的所有键中创建一个集合,但我不确定这是否是一个好方法。
是的,只应保存最高值。
编辑 2
不幸的是,以这种方式更新媒体后我收到错误消息
TypeError: in method 'Reaction_setReversible', argument 2 of type 'bool'
当我尝试将带有更新媒体的模型写入 xml 文件时。
**上次编辑**
如果有人遇到同样的问题,你只需要指定值是浮点数即可。之后一切正常。
你可以使用下面的dictcomp:
dct1 = {'A': 0, 'B': 9, 'C': 9}
dct2 = {'A': 9, 'B': 0}
{key: max(dct1.get(key, 0), dct2.get(key, 0)) for key in dct1.keys() | dct2.keys()}
# {'A': 9, 'C': 9, 'B': 9}
您可以使用 Mykola Zlotko 提供的单行代码,这是一种非常 pythonic 的好方法。或者你可以使用更长的版本,像这样:
for key, value in dict1.keys():
if key in dict2:
dict2[key] = max(dict1[key], dict2[key])
else:
dict2[key] = value
您可以遍历所有 keys
而不是创建临时的 set
对象来保存字典的键,如果字典很大,这很有意义。
from itertools import *
def f(d1, d2):
keys = chain(d1.keys(), d2.keys())
return {k: max(d1.get(k, 0), d2.get(k, 0)) for k in keys}
a = {0: 888, 1: 10, 2: 20, 3: 30, 4: 40}
b = {1: 100, 2: 2, 5: 50}
print(f2(a, b))
print(f2(b, a))
# OUTPUT:
{0: 888, 1: 100, 2: 20, 3: 30, 4: 40, 5: 50}
{1: 100, 2: 20, 5: 50, 0: 888, 3: 30, 4: 40}
我正在研究基因组规模的模型,并试图创建适合两种最佳通量条件的基本培养基。我得到了两本字典,其中包含所需的媒体组件,如下所示:
EX_C00001_ext_b 1.132993
EX_C00011_ext_b 1.359592
EX_E1_ext_b 16.000000
EX_C00034_ext_b 0.000088
EX_C00244_ext_b 0.259407
EX_C00182N_cyt_b 0.006079
EX_C00009_ext_b 0.020942
EX_C01330_ext_b 0.000110
EX_C00080_ext_b 0.258331
EX_C00001_ext_b 0.780699
EX_C14819_ext_b 0.000197
EX_C00059_ext_b 0.005162
EX_C00011_ext_b 1.198398
EX_C14818_ext_b 0.000217
EX_C00305_ext_b 0.000802
EX_C00038_ext_b 0.000088
EX_C00070_ext_b 0.000088
EX_C06232_ext_b 0.000088
EX_C00076_ext_b 0.000131
EX_C00238_ext_b 0.004925
EX_E1_ext_b 16.000000
EX_C00175_ext_b 0.000094
我想合并两个词典,以最优雅的方式为每个代谢物选择最高值,并且无论词典大小如何,它都应该可用。
它应该给我以下结果:
EX_C00034_ext_b 0.000088
EX_C00244_ext_b 0.259407
EX_C00182N_cyt_b 0.006079
EX_C00009_ext_b 0.020942
EX_C01330_ext_b 0.000110
EX_C00080_ext_b 0.258331
EX_C00001_ext_b 1.132993
EX_C14819_ext_b 0.000197
EX_C00059_ext_b 0.005162
EX_C00011_ext_b 1.359592
EX_C14818_ext_b 0.000217
EX_C00305_ext_b 0.000802
EX_C00038_ext_b 0.000088
EX_C00070_ext_b 0.000088
EX_C06232_ext_b 0.000088
EX_C00076_ext_b 0.000131
EX_C00238_ext_b 0.004925
EX_E1_ext_b 16.000000
EX_C00175_ext_b 0.000094
以下是供您使用的示例字典。
{'EX_C00034_ext_b': 8.757888959017035e-05, 'EX_C00244_ext_b': 0.2594073529471562, 'EX_C00182N_cyt_b': 0.006078784247428623, 'EX_C00009_ext_b': 0.02094224214212716, 'EX_C01330_ext_b': 0.00010954587179767827, 'EX_C00080_ext_b': 0.2583314448433369, 'EX_C00001_ext_b': 0.7806992563484072, 'EX_C14819_ext_b': 0.00019712476138777617, 'EX_C00059_ext_b': 0.005162038491279668, 'EX_C00011_ext_b': 1.1983981620820985, 'EX_C14818_ext_b': 0.00021724189246195394, 'EX_C00305_ext_b': 0.0008020492051022175, 'EX_C00038_ext_b': 8.757888959017035e-05, 'EX_C00070_ext_b': 8.757888959017036e-05, 'EX_C06232_ext_b': 8.757888959017035e-05, 'EX_C00076_ext_b': 0.00013122381476546977, 'EX_C00238_ext_b': 0.0049252286422986884, 'EX_E1_ext_b': 16.000000000000245, 'EX_C00175_ext_b': 9.42845999482296e-05}
{'EX_C00001_ext_b': 1.1329932376320115, 'EX_C00011_ext_b': 1.3595918851584152, 'EX_E1_ext_b': 16.000000000000387}
请注意,我不知道哪个字典中有更高的值。
编辑
正如您从我的示例中看到的,即使两个字典都包含相同的键,但并非所有键都在两个字典中。所以我无法遍历这些键,因为我不知道我是否跳过了其中一个键。 我想你可以先从我需要合并的所有字典中的所有键中创建一个集合,但我不确定这是否是一个好方法。
是的,只应保存最高值。
编辑 2
不幸的是,以这种方式更新媒体后我收到错误消息
TypeError: in method 'Reaction_setReversible', argument 2 of type 'bool'
当我尝试将带有更新媒体的模型写入 xml 文件时。
**上次编辑**
如果有人遇到同样的问题,你只需要指定值是浮点数即可。之后一切正常。
你可以使用下面的dictcomp:
dct1 = {'A': 0, 'B': 9, 'C': 9}
dct2 = {'A': 9, 'B': 0}
{key: max(dct1.get(key, 0), dct2.get(key, 0)) for key in dct1.keys() | dct2.keys()}
# {'A': 9, 'C': 9, 'B': 9}
您可以使用 Mykola Zlotko 提供的单行代码,这是一种非常 pythonic 的好方法。或者你可以使用更长的版本,像这样:
for key, value in dict1.keys():
if key in dict2:
dict2[key] = max(dict1[key], dict2[key])
else:
dict2[key] = value
您可以遍历所有 keys
而不是创建临时的 set
对象来保存字典的键,如果字典很大,这很有意义。
from itertools import *
def f(d1, d2):
keys = chain(d1.keys(), d2.keys())
return {k: max(d1.get(k, 0), d2.get(k, 0)) for k in keys}
a = {0: 888, 1: 10, 2: 20, 3: 30, 4: 40}
b = {1: 100, 2: 2, 5: 50}
print(f2(a, b))
print(f2(b, a))
# OUTPUT:
{0: 888, 1: 100, 2: 20, 3: 30, 4: 40, 5: 50}
{1: 100, 2: 20, 5: 50, 0: 888, 3: 30, 4: 40}