gpt4 book ai didi

dictionary - 你如何遍历两个字典并在同一路径上获取值?

转载 作者:行者123 更新时间:2023-11-28 19:40:28 31 4
gpt4 key购买 nike

我有两本结构相似的字典……这意味着它们(应该)具有相同的键结构,即使在嵌套键中也是如此。此外,这些字典几乎可以具有任何类型的嵌套结构...列表、字典等...我希望能够遍历这些字典,获取这两个值并从函数中返回它们。

简单示例:

dict_a = {'a':1, 'b':2, 'c':{'d':3}}
dict_b = {'a':2, 'b':4, 'c':{'d':6}}
#Note the structure is the same for these dicts
#I want to be able to do something like:
>>get_values( dict_a, dict_b)
[(1,2),(2,4),(3,6)]

我自己想出了一个解决方案,方法是遍历一个字典,然后将每个键(或遇到列表的索引)附加到列表中……作为一种键路径:

key_map = []#A list of all key-paths for a dictionary
generate_key_paths(dict_a, [], key_map)
def generate_key_paths(value, key_list,key_map ):

new_list = [item for item in key_list]
if isinstance( value, dict):
#Handle list
for key, val in value.iteritems():
new_list.append( key)
self._generate_key_paths( val, new_list, key_map )
new_list = [item for item in key_list]

elif isinstance( value, list ):
#Handle list
for idx,item in enumerate(value):
new_list.append( idx )
self._generate_key_paths( item, new_list, key_map )
new_list = [item for item in key_list]
else:
#Handle data--reached farthest point you can go
#So just append (key-path, value) to key_map
key_map.append((new_list, value ) )

然后一旦你有了键路径列表,值元组......走这条路,并尝试到达它在第二个字典上获取它的值...

val_list = []
for item in key_map:
value = get_value( item[0] )
if value is not None:
val_list.append( (item[1], value ) )
def get_value( key_list ):
value = dict_b
for item in key_list:
try:
value = value[item]
except:
value = None
break
return value

这对于字典可能具有的所有结构都非常有效,但看起来工作量很大。有没有更多的pythonic方式来实现这一目标?有没有更快、更有效的方法?

编辑:我正在寻找一个不是列表或字典的值,所以当达到这些值时,它应该在它们内部迭代,直到找到一个值。保证如果它是一个列表,它将是一个字典列表,因此应该始终遵循某种键:值关系。

例如一个可能的字典可能是这样的:

dict_a = {'a':1, 'b':2, 'c':[{'d':5},{'e':6}]}

dict_b = {'a':2, 'b':4, 'c':[{'d':10},{'e':12}]}

答案:[(1,2), (2,4), (5,10), (6,12)]

最佳答案

您正在寻找 flatten(zipTree(...)) 的等价物(函数不存在但其名称应该能表达我的观点)。

from collections import Mapping

def treezipFlat(t1,t2):
if isinstance(t1,Mapping) and isinstance(t2,Mapping):
assert set(t1)==set(t2)
for k,v1 in t1.items():
v2 = t2[k]
for tuple in treezipFlat(v1,v2):
yield tuple
else:
yield (t1,t2)

演示:

>>> dict_a = {'a':1, 'b':2, 'c':{'d':3}}
>>> dict_b = {'a':2, 'b':4, 'c':{'d':6}}
>>> list( treezipFlat(dict_a, dict_b) )
[(1, 2), (3, 6), (2, 4)]

您还可以通过像这样扩充函数来生成路径元组:

from collections import Mapping

def treezipItems(t1,t2, path=[]):
if isinstance(t1,Mapping) and isinstance(t2,Mapping):
assert set(t1)==set(t2)
for k,v1 in t1.items():
v2 = t2[k]
for tuple in treezipItems(v1,v2, path=path+[k]):
yield tuple
else:
yield (path, (t1,t2))

>>> list( treezipItems(dict_a, dict_b) )
[(['a'], (1, 2)), (['c', 'd'], (3, 6)), (['b'], (2, 4))]

恕我直言,我觉得这里很自然的是一个名为 treezip 的函数:

def treezip(t1,t2):
if isinstance(t1,Mapping) and isinstance(t2,Mapping):
assert set(t1)==set(t2)
R = {}
for k,v1 in t1.items():
v2 = t2[k]
R[k] = treezip(v1,v2)
return R
else:
return (t1,t2)

>>> from pprint import pprint as pp
>>> treezip(dict_a, dict_b)
{'a': (1, 2), 'c': {'d': (3, 6)}, 'b': (2, 4)}

然后是一个名为 flattenValues 的函数(如果您想保留键,则称为 flattenItems)。

关于dictionary - 你如何遍历两个字典并在同一路径上获取值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10306672/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com