我正在解决包含化学反应及其相关电压的字典的问题。字典是从.txt文件制作的,我非常希望能够输入所需的电压(即2),并让代码给我反应最接近输入的值。
.txt文件看起来像这样(缩短了):
left side of reaction|right side of reaction|voltage.
F2(g)+2e–|2F–(aq)|+2.87
Co3+(aq)+e–|Co2+(aq)|+1.82
Pb4+(aq)+2e–|Pb2+(aq)|+1.8
H2O2(aq)+2H+(aq)+2e–|2H2O|+1.77
我在这里制作了这段代码,将电压作为键,只将反应的左侧作为值。
from collections import defaultdict
import operator
with open('redoxacid.txt', 'r') as document:
next(document)
answer = {}
for line in document:
line = line.strip('\n')
line = line.split('|')
if not line:
continue
answer[line[0]] = line[2] #here we have the reactions as key, and volt as value.
res = dict((v, k) for k, v in answer.items()) #flipping values in dictionary
sorted(answer.items(), key=lambda x: x[-1])
#print(res)
userinput = input("Voltage? ")
for k, v in res.items():
print(k,v) #I now have two values here, voltage and reaction
#?????
当我打印时,我得到了这个:
+2.87 F2(g)+2e–
+1.82 Co3+(aq)+e–
+1.8 Pb4+(aq)+2e–
+1.77 H2O2(aq)+2H+(aq)+2e–
+1.7 NiO2(s)+4H+(aq)+2e–
....and so on
我现在如何获取用户输入(数字)并在我的dict / list中找到最类似的值?
如果我接受输入= 2,则代码找到大约等于该值的值并打印相应的反应。
答案 0 :(得分:3)
首先,我建议使用与dict不同的数据结构,原因如下:
关于dicts的好处是在给出密钥时可以快速访问元素。但是,你不知道密钥,你只知道一些接近密钥的东西 - 因此你需要迭代dict。
dict的问题在于它需要一定的电压才能恰好与一种化学反应相关联。即使你使用的化学反应子集也是如此,我仍然建议你从一开始就试着避免这个问题。
相反,为什么不使用元组列表(这里,我们将输入文件中的电压字符串转换为浮点数)
res = [(float(v), k) for k, v in answer.items()]
现在你必须定义两个电压接近的含义。例如
def approximatelyEqual(v1, v2):
epsilon = 0.001 # Define this however you want
return abs(v1 - v2) < epsilon
一旦你有了这个,其余的很简单
similarChemicalReactions = [(voltage, reaction) for (voltage, reaction) in res if approximatelyEqual(voltage, userinput)]
为您提供近似化学反应的清单。如果你想要最近的一个,请执行:
similarChemicalReaction = min(((voltage, reaction) for (voltage, reaction) in res), key=lambda v1: approximatelyEqual(v1, userinput))
答案 1 :(得分:1)
迭代你的键,计算每个键和用户输入之间的绝对差值,返回最小差值。
min = 9999 # arbitrarily high minimum difference
minKey = 0 # start (this is also arbitrary and will be replaced)
for key in res: # iterate through dict keys
if abs(userinput-float(res[key].strip('+-')))<min: # if key is closer than the previously-found closest key
minKey = key # update minKey
print res[minKey] # output result
答案 2 :(得分:1)
此解决方案假设abs(user_input_value - key_val) < 1
:
file_data = [i.strip('\n').split("|") for i in open('filename.txt')]
d = {float(c[1:]):a for a, b, c in file_data}
val = int(input("enter voltage: "))
possibilities = [b for a, b in d.items() if abs(val-a) < 1]
final_reactions = "None found" if not possibilities else ', '.join(possibilities)