我试图制作一个潜水表,其中有一些数字不是我能看到的模式,所以我必须手动添加所有值,但我需要抓住输入和圆形它是字典中最接近的数字。
我需要将输入转换回字符串以使输出正确:
CODE:
class DepthTable:
def __init__(self):
self.d35 = {"10": "A",
"19": "B",
"25": "C",
"29": "D",
"32": "E",
"36": "F",
}
def getpressureGroup(self, depth, time):
if depth == "35":
output = self.d35[time]
else:
output = "No info for that depth"
print(output)
if __name__ == "__main__":
depthtable = DepthTable()
print("Please enter Depth (Use numbers!)")
depth = input()
print("Please Enter time!")
time = input()
depthtable.getpressureGroup(depth,time)
所以当"播放器"输入数字15的时间,我需要将它向上舍入到19(即使它是13或类似的东西也总是向上。)我不知道如何用圆()或我做到这一点可能必须创建一个检查每个数字的函数..
答案 0 :(得分:2)
将d35
字典转换为已排序的列表并逐步执行:
In [4]: d35 = {"10": "A",
...: "19": "B",
...: "25": "C",
...: "29": "D",
...: "32": "E",
...: "36": "F",
...: }
In [5]: sorted(d35.items())
Out[5]: [('10', 'A'), ('19', 'B'), ('25', 'C'), ('29', 'D'), ('32', 'E'), ('36', 'F')]
In [7]: time = 15
In [11]: for max_time, group_name in sorted(d35.items()):
...: if int(max_time) >= time:
...: break
...:
In [12]: max_time
Out[12]: '19'
In [13]: group_name
Out[13]: 'B'
修改你的方法就可以了。我在for循环中添加了一个else来处理任何组都没有覆盖的时间。
def getpressureGroup(self, depth, time):
if depth == "35":
for max_time, group_name in sorted(self.d35.items()):
if int(max_time) >= time:
output = group_name
break
else:
output = "No info for that depth"
else:
output = "No info for that depth"
print(output)
答案 1 :(得分:2)
使用“检查每个数字的函数”的想法,可以使用实例变量keys
来获取密钥(如果存在)或下一个最高密钥:
class DepthTable:
def __init__(self):
self.d35 = {10: "A",
19: "B",
25: "C",
29: "D",
32: "E",
36: "F",
}
self.keys = self.d35.keys()
def getpressureGroup(self, depth, time):
if depth == 35:
rtime = min([x for x in self.keys if x >= time]) # if exists get key, else get next largest
output = self.d35[rtime]
else:
output = "No info for that depth"
print(output)
if __name__ == "__main__":
depthtable = DepthTable()
print("Please enter Depth (Use numbers!)")
depth = int(input())
print("Please Enter time!")
time = int(input())
depthtable.getpressureGroup(depth,time)
演示:
Please enter Depth (Use numbers!)
35
Please Enter time!
13
B
Please enter Depth (Use numbers!)
35
Please Enter time!
19
B
Please enter Depth (Use numbers!)
35
Please Enter time!
10
A
答案 2 :(得分:1)
对于大型列表,请使用标准bisect模块或任何其他二分法包。 查看友好的python文档,了解如何使用bisect
解决您的任务的精确指令https://docs.python.org/2/library/bisect.html#other-examples
如果你有numpy,尝试数字化,似乎比pandas cut更容易
Python: Checking to which bin a value belongs
然而,对于这样的短名单,我只会使用简单的分支
if 1<x<=18:
...
elif 18<x<=28:
...
elif
或者,为了更高速度构建个案数组或字典 {&#34; 1&#34;:&#34; 19&#34;,&#34; 2&#34;:&#34; 19&#34; ......&#34; 20&#34;:&#34; 25&#34; ...}以编程方式,
使用activestate字典反转片段
http://code.activestate.com/recipes/415100-invert-a-dictionary-where-values-are-lists-one-lin/
def invert(d):
return dict( (v,k) for k in d for v in d[k] )
d35 = {"10": "A",
"19": "B",
"25": "C",
"29": "D",
"32": "E",
"36": "F",
}
dlist = d35.keys().sort()
d1 = {}
low = -1
for n in dlist[1:]:
up = int(n) + 1
interval = range(low, up)
low = up
d1[ dlist[i] ] = map(str, interval)
result = invert(d1)
答案 3 :(得分:1)
您可以尝试使用cut
模块中的pandas
。
或多或少,它将连续变量分成不连续的类别,例如压力组的深度。
您需要指定一个容器数组来剪切数据,然后您可以将其标记。
所以,举个例子:
import pandas as pd
import numpy as np
timestocut = [0, 4, 8, 12, 16, 20, 24, 28, 32, 36]
pd.cut(timestocut, bins = np.array([-1,10,19,25,29,32, np.inf]), labels = np.array(['A','B','C','D','E','F']), right = True)
,并提供:
[A, A, A, B, B, C, C, D, E, F]
Categories (6, object): [A < B < C < D < E < F]
你可以看到这些箱子有-1,所以我们包括0,np.inf
来捕捉任何无限的东西。
将它集成到您的代码中取决于您 - 我个人会删除该dict并使用此映射。
答案 4 :(得分:1)
虽然bisect
和pandas.cut
(如其他答案中所述)可行,但您可以通过循环切换值来使用vanilla Python(无导入模块)。 (这是@Harvey's answer中的方法,仅作为程序而非交互式会话呈现。)
d35 = {
10: "A",
19: "B",
25: "C",
29: "D",
32: "E",
36: "F",
}
def pressure_group(time):
for cutoff in sorted(d35.items()):
if cutoff[0] >= time:
return cutoff[1]
return None # or pick something else for "too high!"
这比使用上面提到的模块更加冗长,但也许更容易理解和理解正在发生的事情,因为你自己都这样做(我认为这通常是一个好主意,特别是如果你试图学习编程)。
每次循环时,cutoff
都是d35
字典中的一对。由于对从最低到最高排序,您可以在第一个大于或等于输入的位置停止。如果循环结束(因为输入高于最高截止值),我选择返回None
,但您可以返回其他值,或者引发异常。