如何将 if else 逻辑转换为动态选择?
Posted
技术标签:
【中文标题】如何将 if else 逻辑转换为动态选择?【英文标题】:How to convert the if else logic into dynamic selection? 【发布时间】:2020-12-18 01:24:07 【问题描述】:我正在编写逻辑来比较几个值。
我有三个值列表和一个规则列表
new_values = [1,0,0,0,1,1]
old_1 = [1,1,1,0,0,1]
old_2 = [1,0,1,0,1,1]
# when a is correct #when b is correct # if both are correct # if both are wrong
rules = ['a', 'b', 'combine', 'leave']
我正在寻找的是,根据规则列表中的选择规则将 new_values 与 old_1 和 old_2 值进行比较。
类似这样的:
def logic(new_values, old_values, rules):
rules_result = []
for new_value, old_value_1, old_value_2 in zip(new_values, old_values[0], old_values[1]):
if new_value == old_value_1 and new_value == old_value_2:
# if both are correct
rules_result.append(rules[2])
elif new_value == old_value_1:
# if a is correct
rules_result.append(rules[0])
elif new_value == old_value_2:
# if b is correct
rules_result.append(rules[1])
elif new_value!= old_value_1 and new_value!= old_value_2:
# if both are wrong
rules_result.append(rules[3])
return rules_result
用一个规则列表运行这段代码会给我这个结果:
logic(new_values, [old_1, old_2], rules)
输出
['combine', 'b', 'leave', 'combine', 'b', 'combine']
如果我必须比较两个以上的旧值列表,我将面临使此代码动态化的问题,假设我有三个旧值列表,然后我的规则列表将为每个组合扩展
new_values = [1,0,0,0,1,1]
old_1 = [1,1,1,0,0,1]
old_2 = [1,0,1,0,1,1]
old_3 = [0,0,0,1,1,1]
# when a is correct #when b is correct # if a and b are correct # if a and c are correct #if b and c are correct' #if all three are correct # if all three are wrong
rules = ['a', 'b', 'combine a_b', 'select c', 'combine b_c', 'select a', 'combine']
我正在从不同的函数中获取规则和值,我正在寻找一个规则选择函数,其中将旧值列表(例如 2,3,4 列表)与新值和规则列表一起传递,然后动态比较每个带有新值列表的旧列表并从规则列表中选择规则。
如何使逻辑函数动态处理两个以上的旧列表值?
【问题讨论】:
是否还有其他 20 个 old_X 输入? 为什么new == a && new ==b
的文本与new == a & new == c
不同(一次是“合并”,一次是“选择”)?
为什么标签列表中有pandas? pandas 在这方面没有任何作用。
【参考方案1】:
如果您使用truth table 的概念,这个问题很容易解决。您的rules
列表定义了一些布尔值的结果。它不是由 1 和 0 组成,因此不能用 and
、or
、xor
等真值函数表示,但这不是问题。您可以通过考虑真值表中的顺序来简单地重新排列您的列表:
# for 2 boolean variables, there are 2 ^ 2 = 4 possibilities
# ab ab ab ab
# 00 01 10 11
rules = ["leave", "b", "a", "combine"]
你也可以把它变成dict
,这样你就不需要评论它们来记住哪个是什么(作为奖励,它看起来像一个真值表:)):
# ab
rules = "00": "leave",
"01": "b",
"10": "a",
"11": "combine"
现在,定义一个函数来获取布尔变量的相关键值:
def get_rule_key(reference, values):
""" compares all the values against reference and returns a string for the result"""
return "".join(str(int(value == reference)) for value in values)
您的logic
函数将是这样的:
def logic(new_values, old_values, rules):
rules_result = []
for new_value, *old_values in zip(new_values, *old_values):
key = get_rule_key(new_value, old_values)
rules_result.append(rules.get(key))
return rules_result
print(logic(new_values, [old_1, old_2], rules))
# ['combine', 'b', 'leave', 'combine', 'b', 'combine']
对于三元组,请相应地更新您的 rules
:
# for 3 boolean variables, there are 2 ^ 3 = 8 possibilities
# abc
rules = "000": "combine",
# "001": Not defined in your rules,
"010": "b",
"011": "combine b_c",
"100": "a",
"101": "select c",
"110": "combine a_b"
"111": "select a"
print(logic(new_values, [old_1, old_2, old_3], rules))
# ['combine a_b', 'combine b_c', None, 'combine a_b', 'combine b_c', 'select a']
注意事项:
None
出现在输出中,因为您的 rules
没有定义 "001"
的输出,而 dict.get
默认返回 None
。
如果您想使用list
定义规则,您必须按顺序定义所有 规则并将get_rule_key
的结果转换为整数:"011" -> 3
。您可以通过 int(x, base=2)
管理此问题。
【讨论】:
【参考方案2】:如果输入未知,则很难获得您指定的标签。
很容易映射哪些旧值对应于相同的新值(从位置上讲)。您可以使用通用测试函数获取“新”值和该位置上的所有“旧”值,将旧值映射到 'a'...
并返回相关的值:
new_values = [1,0,0,0,1,1]
old_1 = [1,1,1,0,0,1]
old_2 = [1,0,1,0,1,1]
old_3 = [0,0,0,1,1,1]
old_4 = [0,0,0,1,1,1]
old_5 = [0,0,0,1,1,1]
def test(args):
nv, remain = args[0], list(args[1:])
start = ord("a")
# create dict from letter to its corresponding value
rv = chr(start + i):v for i,v in enumerate(remain)
# return tuples of the input and the matching outputs
return ((nv,remain), [k for k,v in rv.items() if v == nv])
rv = []
for values in zip(new_values, old_1, old_2, old_3, old_4, old_5):
rv.append(test(values))
print(*rv,sep="\n")
print([b for a,b in rv])
输出(手动间隔):
# nv old_1 old_2 old_3 old_4 old_5
# a b c d e
((1, [ 1, 1, 0, 0, 0]), ['a', 'b'])
((0, [ 1, 0, 0, 0, 0]), ['b', 'c', 'd', 'e'])
((0, [ 1, 1, 0, 0, 0]), ['c', 'd', 'e'])
((0, [ 0, 0, 1, 1, 1]), ['a', 'b'])
((1, [ 0, 1, 1, 1, 1]), ['b', 'c', 'd', 'e'])
((1, [ 1, 1, 1, 1, 1]), ['a', 'b', 'c', 'd', 'e'])
[['a', 'b'], ['b', 'c', 'd', 'e'], ['c', 'd', 'e'], ['a', 'b'],
['b', 'c', 'd', 'e'], ['a', 'b', 'c', 'd', 'e']]
然后您可以将连接的结果映射到一些输出:
# mapping needs completion - you'll need to hardcode that
# but if you consider inputs up to 5 old values, you need to specify those
# combinations that can happen for 5 as 4,3,2 are automagically included
# iif you omit "all of them" as result.
mapper = "a": "only a", "ab": "a and b", "ac":"a and c", "abcde": "all of them",
# complete to your statisfaction on your own
for inp, outp in rv:
result = ''.join(outp)
print(mapper.get(result , f"->'result' not mapped!"))
获得以下输出:
a and b
->'bcde' not mapped!
->'cde' not mapped!
a and b
->'bcde' not mapped!
all of them
【讨论】:
以上是关于如何将 if else 逻辑转换为动态选择?的主要内容,如果未能解决你的问题,请参考以下文章
If-then-else 逻辑来决定运行哪个 select 语句
循环运行时出现 Java 逻辑错误:If/else 计数器计数不正确
帮助! - SQL - IF Else IF 逻辑用于返回 Containstable 选择