在Python 3.6

时间:2017-04-13 17:35:21

标签: python python-3.6

我试图制作一个潜水表,其中有一些数字不是我能看到的模式,所以我必须手动添加所有值,但我需要抓住输入和圆形它是字典中最接近的数字。

我需要将输入转换回字符串以使输出正确:

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或类似的东西也总是向上。)我不知道如何用圆()或我做到这一点可能必须创建一个检查每个数字的函数..

5 个答案:

答案 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)

虽然bisectpandas.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,但您可以返回其他值,或者引发异常。