我正在嘗試將一些值從資料映射到模板。
我只想在模板中填充值(通過一些操作),如果它們已經存在于模板中。
我的模板有數百個鍵,我的目標是避免在每次操作和賦值之前使用 if 陳述句。
if 陳述句的重點是推遲對我正在執行的操作的評估,因為它們執行起來可能很昂貴。任何解決方案都應考慮到這一點。
data = {
'a':1,
'b':2,
'c':3,
'd':4,
'e':5
}
template1 = {
'p':'Nan',
'q':'Nan',
'r':'Nan'
}
template2 = {
'p':'Nan',
's':'Nan',
't':'Nan'
}
def func(template,data):
if 'p' in template.keys():
template['p'] = data['a']
if 'q' in template.keys():
template['q'] = data['b'][:2] 'some manipulation'
if 'r' in template.keys():
template['r'] = data['c']
if 's' in template.keys():
template['s'] = data['d'] 'some mainpulation'
if 't' in template.keys():
template['t'] = data['e']
我知道我缺少一些基本的東西,我的實際代碼和需求非常復雜,我試圖簡化它們并將它們歸結為這個簡單的結構。提前感謝您的幫助!
uj5u.com熱心網友回復:
您還可以使用 lambda 函式將操作直接存盤在資料字典中,然后在使用此字典更新模板時檢查從資料字典中檢索到的任何值是否為 callable()。假設您無法修改 data dict 中的鍵,那么這種方法仍然可以與 Jlove 建議的 template_dict 映射方法一起使用。
data = {
'p': 1,
'q': 2,
'r': 3,
's': 4,
't': 5,
'u': lambda x: x * 2
}
template1 = {
'p':'Nan',
'q':'Nan',
'r':'Nan',
'u': 2
}
def func(template, data):
for key in template:
if callable(data[key]):
template[key] = data[key](template[key])
else:
template[key] = data[key]
#driver
func(template1, data)
for k in template1.items():
print(k)
--- 基于評論的擴展解決方案 ---
與上面基本相同,但展示了如何使用映射字典來指導資料字典和動作字典如何組合以修改模板字典。還展示了如何使用字典將鍵映射到函式。
from collections import defaultdict
def qManipulation(x):
return x * 10
def sManipulation(x):
return x * 3
data = {
'a':1,
'b':2,
'c':3,
'd':4,
'e':5
}
actions = {
'q': qManipulation,
's': sManipulation,
'u': lambda x: x * 7
}
tempToDataMap = defaultdict(lambda: None, {
'p': 'a',
'q': 'b',
'r': 'c',
's': 'd',
't': 'e'
})
template1 = {
'p':'Nan',
'q':'Nan',
'r':'Nan',
'u': 2
}
def func(template, data):
for key, val in template.items():
dataKey = tempToDataMap[key]
# check if the template key corrosponds to a data dict key
if dataKey is not None:
# if key mapping from template to data is actually in data dict, use data value in template
if dataKey in data:
template[key] = data[dataKey]
# if the template key is registered to an action in action dict, run action
if key in actions:
template[key] = actions[key](data[dataKey])
# use this if you have a manipulation on a template field that is not populated by data.
# this isn't present in the example, but could be handy if the template ever has default values other that Nan
elif key in actions:
template[key] = actions[key](template[key])
func(template1, data)
for k in template1.items():
print(k)
uj5u.com熱心網友回復:
如果您的操作可以表示為一個簡單的 lambda,您可以將條件/賦值封裝在一個函式中以減少代碼混亂:
def func(template,data):
def apply(k,action):
if k in template: template[k] = action()
apply('p',lambda: data['a'])
apply('q',lambda: data['b'][:2] 'some manipulation')
apply('r',lambda: data['c'])
apply('s',lambda: data['d'] 'some mainpulation')
apply('t',lambda: data['e'])
uj5u.com熱心網友回復:
這可能不是一個好主意,但您可以子類化dict和覆寫__setitem__.
class GuardDict(dict):
def __setitem__(self, key, callable_value):
if key in self:
super().__setitem__(key, callable_value())
# we need a method to transform back to a dict
def to_dict(self):
return dict(self)
data = {
'a': 1,
'b': '2',
'c': 3,
'd': '4',
'e': 5
}
template1 = {
'p':'Nan',
'q':'Nan',
'r':'Nan'
}
template2 = {
'p':'Nan',
's':'Nan',
't':'Nan'
}
def func(template,data):
# create a GuardDict from the dict
# this will utilize __setitem__ and only actually set keys
# that already exist in the original dict
template = GuardDict(template)
template['p'] = lambda: data['a']
template['q'] = lambda: data['b'] 'some manipulation'
template['r'] = lambda: data['c']
template['s'] = lambda: data['d'] 'some mainpulation'
template['t'] = lambda: data['e']
# set back to a dict
return template.to_dict()
template1 = func(template1, data)
template2 = func(template2, data)
print(template1)
print(template2)
我可能應該注意,如果您的代碼還有其他用戶,他們可能會因此而討厭您。
uj5u.com熱心網友回復:
動態函式式方法可能會使您擺脫所有 ifs 和 elses,但可能會使整個程式結構復雜化。
data = {
'a':1,
'b':2,
'c':3,
'd':4,
'e':5
}
template1 = {
'p': 'Nan',
'q': 'Nan',
'r': 'Nan'
}
template2 = {
'p': 'Nan',
's': 'Nan',
't': 'Nan'
}
# first, define your complex logic in functions, accounting for every possible template key
def p_logic(data, x):
return data[x]
def q_logic(data, x):
return data[x][:2] 'some manipulation'
# Then build a dict of every possible template key, the associated value and reference to one of the
# functions defined above
logic = {
'p': {
'value': 'a',
'logic': p_logic
},
'q': {
'value': 'b',
'logic': q_logic
},
}
def func(template, data):
# for every key in a template, lookup that key in our logic dict
# grab the value from the data
# and apply the complex logic that has been defined for this template value
for item in template: # template.keys() is not necessary!
template[item] = logic[item]['logic'](data, logic[item]['value'])
uj5u.com熱心網友回復:
我唯一能想到在這里做的就是使用某種 dict 并通過 for 回圈來運行您的模板。如:
template_dict = {'p': 'a', 'q': 'b', 'r': 'c', 's': 'd', 't': 'e'}
def func(template, data):
for key, value in template_dict.items():
if key in template.keys():
template[key] = data[value]
否則,我不確定您如何能夠避免所有這些條件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/373919.html
下一篇:只回傳出現次數最多的元素
