假设我有一本非常复杂的词典。
{'fruit':'orange','colors':{'dark':4,'light':5}}
无论如何,我的目标是在这个复杂的多级词典中扫描每个键。然后,将“abc”附加到每个键的末尾。
所以它将是:
{'fruitabc':'orange','colorsabc':{'darkabc':4,'lightabc':5}}
你会怎么做?
答案 0 :(得分:35)
无法更改密钥。您将需要添加具有修改值的新键,然后删除旧键,或者创建具有词典理解等的新词典。
答案 1 :(得分:14)
例如:
def appendabc(somedict):
return dict(map(lambda (key, value): (str(key)+"abc", value), somedict.items()))
def transform(multilevelDict):
new = appendabc(multilevelDict)
for key, value in new.items():
if isinstance(value, dict):
new[key] = transform(value)
return new
print transform({1:2, "bam":4, 33:{3:4, 5:7}})
这会将“abc”附加到字典中的每个键以及任何字典值。
编辑:还有一个非常酷的Python 3版本,请查看:
def transform(multilevelDict):
return {str(key)+"abc" : (transform(value) if isinstance(value, dict) else value) for key, value in multilevelDict.items()}
print(transform({1:2, "bam":4, 33:{3:4, 5:7}}))
答案 2 :(得分:9)
>>> mydict={'fruit':'orange','colors':{'dark':4,'light':5}}
>>> def f(mydict):
... return dict((k+"abc",f(v) if hasattr(v,'keys') else v) for k,v in mydict.items())
...
>>> f(mydict)
{'fruitabc': 'orange', 'colorsabc': {'darkabc': 4, 'lightabc': 5}}
答案 3 :(得分:6)
我的理解是你无法更改密钥,并且需要创建一组新密钥并将其值分配给原始密钥指向的密钥。
我会做类似的事情:
def change_keys(d):
if type(d) is dict:
return dict([(k+'abc', change_keys(v)) for k, v in d.items()])
else:
return d
new_dict = change_keys(old_dict)
答案 4 :(得分:5)
我使用以下实用程序函数,我编写了一个目标字典和另一个包含翻译的字典,并根据它切换所有键:
def rename_keys(d, keys):
return dict([(keys.get(k), v) for k, v in d.items()])
所以初始数据:
data = { 'a' : 1, 'b' : 2, 'c' : 3 }
translation = { 'a' : 'aaa', 'b' : 'bbb', 'c' : 'ccc' }
我们得到以下信息:
>>> data
{'a': 1, 'c': 3, 'b': 2}
>>> rename_keys(data, translation)
{'aaa': 1, 'bbb': 2, 'ccc': 3}
答案 5 :(得分:2)
#! /usr/bin/env python
d = {'fruit':'orange', 'colors':{'dark':4,'light':5}}
def add_abc(d):
newd = dict()
for k,v in d.iteritems():
if isinstance(v, dict):
v = add_abc(v)
newd[k + "abc"] = v
return newd
d = add_abc(d)
print d
答案 6 :(得分:1)
像这样的东西
def applytoallkeys( dic, func ):
def yielder():
for k,v in dic.iteritems():
if isinstance( v, dict):
yield func(k), applytoallkeys( v, func )
else:
yield func(k), v
return dict(yielder())
def appendword( s ):
def appender( x ):
return x+s
return appender
d = {'fruit':'orange','colors':{'dark':4,'light':5}}
print applytoallkeys( d, appendword('asd') )
我有点像功能风格,你可以只阅读最后一行并看看它的作用; - )
答案 7 :(得分:1)
这是一个很小的功能:
def keys_swap(orig_key, new_key, d):
d[new_key] = d.pop(orig_key)
针对您的特定问题:
def append_to_dict_keys(appendage, d):
#note that you need to iterate through the fixed list of keys, because
#otherwise we will be iterating through a never ending key list!
for each in d.keys():
if type(d[each]) is dict:
append_to_dict_keys(appendage, d[each])
keys_swap(each, str(each) + appendage, d)
append_to_dict_keys('abc', d)
答案 8 :(得分:0)
你可以用递归来做到这一点:
import collections
in_dict={'fruit':'orange','colors':{'dark':4,'light':5}}
def transform_dict(d):
out_dict={}
for k,v in d.iteritems():
k=k+'abc'
if isinstance(v,collections.MutableMapping):
v=transform_dict(v)
out_dict[k]=v
return out_dict
out_dict=transform_dict(in_dict)
print(out_dict)
# {'fruitabc': 'orange', 'colorsabc': {'darkabc': 4, 'lightabc': 5}}
答案 9 :(得分:0)
您还应该考虑嵌套列表中存在嵌套dicts的可能性,上述解决方案不会涵盖这些内容。此函数会为字典中的每个键添加前缀和/或后缀。
def transformDict(multilevelDict, prefix="", postfix=""):
"""adds a prefix and/or postfix to every key name in a dict"""
new_dict = multilevelDict
if prefix != "" or postfix != "":
new_key = "%s#key#%s" % (prefix, postfix)
new_dict = dict(map(lambda (key, value): (new_key.replace('#key#', str(key)), value), new_dict.items()))
for key, value in new_dict.items():
if isinstance(value, dict):
new_dict[key] = transformDict(value, prefix, postfix)
elif isinstance(value, list):
for index, item in enumerate(value):
if isinstance(item, dict):
new_dict[key][index] = transformDict(item, prefix, postfix)
return new_dict
答案 10 :(得分:0)
for k in theDict: theDict[k+'abc']=theDict.pop(k)
答案 11 :(得分:0)
我用它将docopt POSIX兼容的命令行密钥转换为PEP8密钥
(例如“--option” - >“选项”,“” - >“option2”,“FILENAME” - >“filename”)
arguments = docopt.docopt(__doc__) # dictionary
for key in arguments.keys():
if re.match('.*[-<>].*', key) or key != key.lower():
value = arguments.pop(key)
newkey = key.lower().translate(None, '-<>')
arguments[newkey] = value
答案 12 :(得分:0)
嗨,我是新用户,但找到相同问题的答案,我无法完全解决我的问题,我用一个完整的嵌套替换键制作这个小蛋糕,你可以用dict或dict发送列表。 最后你的dicts可以有dict或更多dict嵌套的列表,它全部被你的新密钥需求所取代。 要指示哪个密钥要用新密钥替换,请使用&#34;到&#34;参数发送一个字典。 最后看看我的小例子。 P / D:对不起,我的英文不好。 =)
def re_map(value, to):
"""
Transform dictionary keys to map retrieved on to parameters.
to parameter should have as key a key name to replace an as value key name
to new dictionary.
this method is full recursive to process all levels of
@param value: list with dictionary or dictionary
@param to: dictionary with re-map keys
@type to: dict
@return: list or dict transformed
"""
if not isinstance(value, dict):
if not isinstance(value, list):
raise ValueError(
"Only dict or list with dict inside accepted for value argument.") # @IgnorePep8
if not isinstance(to, dict):
raise ValueError("Only dict accepted for to argument.")
def _re_map(value, to):
if isinstance(value, dict):
# Re map dictionary key.
# If key of original dictionary is not in "to" dictionary use same
# key otherwise use re mapped key on new dictionary with already
# value.
return {
to.get(key) or key: _re_map(dict_value, to)
for key, dict_value in value.items()
}
elif isinstance(value, list):
# if value is a list iterate it a call _re_map again to parse
# values on it.
return [_re_map(item, to) for item in value]
else:
# if not dict or list only return value.
# it can be string, integer or others.
return value
result = _re_map(value, to)
return result
if __name__ == "__main__":
# Sample test of re_map method.
# -----------------------------------------
to = {"$id": "id"}
x = []
for i in range(100):
x.append({
"$id": "first-dict",
"list_nested": [{
"$id": "list-dict-nested",
"list_dic_nested": [{
"$id": "list-dict-list-dict-nested"
}]
}],
"dict_nested": {
"$id": "non-nested"
}
})
result = re_map(x, to)
print(str(result))
答案 13 :(得分:0)
功能(和灵活)解决方案。这允许将任意变换应用于键(递归地用于嵌入的dicts):
def remap_dict(d, keymap_f):
"""returns a new dict by recursively remapping all of d's keys using keymap_f"""
return dict([(keymap_f(k), remap_dict(v, keymap_f) if isinstance(v, dict) else v)
for k,v in d.iteritems()])
让我们尝试一下;首先我们定义我们的关键转换函数,然后将其应用于示例:
def transform_key(key):
"""whatever transformation you'd like to apply to keys"""
return key + "abc"
remap_dict({'fruit':'orange','colors':{'dark':4,'light':5}}, transform_key)
{'fruitabc': 'orange', 'colorsabc': {'darkabc': 4, 'lightabc': 5}}
答案 14 :(得分:0)
基于@AndiDog的python 3版本,类似于@ sxc731的版本,但带有是否递归应用的标志:
<button onclick=showText('text1')>Show text 1</button>
<button onclick=showText('text2')>Show text 2</button>
<button onclick=showText('text3')>Show text 3</button>
<p id="text1"></p>
<p id="text2"></p>
<p id="text3"></p>