首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >寻找蟒蛇的优雅:字典而不是重复的意大利面条块

寻找蟒蛇的优雅:字典而不是重复的意大利面条块
EN

Stack Overflow用户
提问于 2018-07-29 07:27:10
回答 3查看 56关注 0票数 0

我有一个脚本,转换成LaTeX格式的表嵌套列表。棘手的部分与按其值着色的单元格相关。假设我有一个嵌套列表,如下所示:

[0.40,-0.13,0.00,0.00,0.00,-1.90,-0.56,-0.57,-0.66,-1.37,4.07,0.24,2.56,0.02,0.02,6.43,0.23,0.33,0.18,0.02,11.80,4.81,4.86,3.96,6.03,4.05,1.94,0.09,0.01,0.03]

我的脚本的这一部分是这样的

代码语言:javascript
运行
复制
for fila in listainicial:
#seudocódigo
    mes1 = ""
    mes2 = ""
    mes3 = ""
    mes4 = ""
    mes5 = ""
if float(fila[0]) >= 100:
        mes1 = "\\footnotesize{}\\cellcolor{100pc}"
    elif float(fila[0]) > 30:
        mes1 = "\\footnotesize{}\\cellcolor{masde30pc}"
    elif float(fila[0]) > 20:
        mes1 = "\\footnotesize{}\\cellcolor{20to30pc}"
    elif float(fila[0]) > 10:
        mes1 = "\\footnotesize{}\\cellcolor{10to20pc}"
    elif float(fila[0]) > 5:
        mes1 = "\\footnotesize{}\\cellcolor{5to10pc}"
    elif float(fila[0]) > 0:
        mes1 = "\\footnotesize{}\\cellcolor{0to5pc}"
    elif float(fila[0]) == 0:
        mes1 = "\\footnotesize{}\\cellcolor{0pc}"
    elif float(fila[0]) > -5:
        mes1 = "\\footnotesize{}\\cellcolor{m5to0pc}"
    elif float(fila[0]) > -10:
        mes1 = "\\footnotesize{}\\cellcolor{m10tom5pc}"
    elif float(fila[0]) > -25:
        mes1 = "\\footnotesize{}\\cellcolor{m25tom10pc}"
    elif float(fila[0]) <= -25:
        mes1 = "\\footnotesize{}\\cellcolor{menosdem25pc}\\color{white}"

从fila1到fila4重复执行该代码

这太不自然了,让我觉得有点下流。我的脚本工作和复制块不是问题,但正如我在标题中指出的那样,我希望生成更优雅和令人满意的代码。

我真的很想用一本字典来代替这种冗长而单调的if...elif系列。我也会感谢任何其他的解决方案,以减少我的110行的脚本长的部分。

我真的很感激在这方面的任何提示或解决方案

提前感谢

EN

回答 3

Stack Overflow用户

发布于 2018-07-29 09:09:13

这是我试图封装你的代码,让它不那么笨拙:

if name == main上面的所有东西都可以在一个单独的模块中提取出来,让你的主代码看起来像这样:

代码语言:javascript
运行
复制
boundaries = [float('-inf'), -25, -10, -5, 0 - EPSILON, 0 + EPSILON, 5, 10, 20, 30, 100, float('inf')]
listainicial = [the values you have]
latex_string_values =  get_latex_values(listainicial, boundaries)

我添加了文档字符串来解释每个类/方法的作用;如果需要更多解释,请告诉我。

代码语言:javascript
运行
复制
from typing import NamedTuple, List


EPSILON = 1e-8


class Interval(NamedTuple):
    """represents an interval on the number line, where the high value is included
    """
    low : float
    high : float

    def contains(self, value: float)-> bool:
        return self.low < value <= self.high


class Intervals:
    """represents a collection of Interval on the number line
    """
    def __init__(self, boundaries: List[float]):
        self.intervals = [Interval(low=low, high=high)
                          for low, high in zip(boundaries[:-1], boundaries[1:])]

    def get_interval(self, value: float)-> Interval:
        """returns the interval the value belongs to
        """
        for interval in self.intervals:
            if interval.contains(value):
                return interval
        raise ValueError('this value does not belong here')

    def __iter__(self):
        for interval in self.intervals:
            yield interval


class LatexValues:
    """a class that parses and assigns latex strings based on whether a value
    is contained in an interval
    """
    latex_values = ["\\footnotesize{}\\cellcolor{menosdem25pc}\\color{white}",
                    "\\footnotesize{}\\cellcolor{m25tom10pc}",
                    "\\footnotesize{}\\cellcolor{m10tom5pc}",
                    "\\footnotesize{}\\cellcolor{m5to0pc}",
                    "\\footnotesize{}\\cellcolor{0pc}",
                    "\\footnotesize{}\\cellcolor{0to5pc}",
                    "\\footnotesize{}\\cellcolor{5to10pc}",
                    "\\footnotesize{}\\cellcolor{10to20pc}",
                    "\\footnotesize{}\\cellcolor{20to30pc}",
                    "\\footnotesize{}\\cellcolor{masde30pc}",
                    "\\footnotesize{}\\cellcolor{100pc}"
                    ]

    def __init__(self, boundaries: List[List[float]]):

        self.boundaries = boundaries[:]
        self.intervals = Intervals(boundaries)
        self.assigned_values = {interval: latex_value for interval, latex_value
                                in zip(self.intervals, LatexValues.latex_values)}

    def get_latex(self, value: float)-> str:
        return self.assigned_values[self.intervals.get_interval(value)]


def get_latex_values(listainicial: List[List[float]], boundaries: List[float])-> List[List[str]]:
    """
    :param listainicial: a data structure that contains the values used to assign Latex strings
    :param boundaries: the boundaries of the intervals segregating the values
    :return: the appropriate latex string corresponding to a value
             a list of lists that contain the latex_values for mes1-mes5 for each fila in filainicial
    """

    latex_values = LatexValues(boundaries)
    results = []
    for fila in listainicial:
        result = []
        for mes in range(5):
            result.append(latex_values.get_latex(fila[mes]))
        results.append(result)
    return results


if __name__ == '__main__':

    boundaries = [float('-inf'), -25, -10, -5, 0 - EPSILON, 0 + EPSILON, 5, 10, 20, 30, 100, float('inf')]
    test_listainicial = [[0, 22, 43, -200, 1], [12, -4, -12, 110, 41]]
    for result in get_latex_values(test_listainicial, boundaries):
        print(result)

输出:

代码语言:javascript
运行
复制
['\\footnotesize{}\\cellcolor{0pc}', '\\footnotesize{}\\cellcolor{20to30pc}', '\\footnotesize{}\\cellcolor{masde30pc}', '\\footnotesize{}\\cellcolor{menosdem25pc}\\color{white}', '\\footnotesize{}\\cellcolor{0to5pc}']
['\\footnotesize{}\\cellcolor{10to20pc}', '\\footnotesize{}\\cellcolor{m5to0pc}', '\\footnotesize{}\\cellcolor{m25tom10pc}', '\\footnotesize{}\\cellcolor{100pc}', '\\footnotesize{}\\cellcolor{masde30pc}']
票数 2
EN

Stack Overflow用户

发布于 2018-07-29 08:26:02

您可以定义(limit,color)的元组的排序列表:

代码语言:javascript
运行
复制
colors = [(-25,'menosdem25pc'), (-10, 'm25tom10pc'), (-5, 'm10tom5pc')...]

然后,您可以过滤搜索以查找感兴趣的内容:

代码语言:javascript
运行
复制
list_of_bigger_tuples = [x for x in colors where x[0]>fila[0]]
first_tuple = list_of_bigger_tuples[0]
color = first_tuple[1]

现在,您可以编写字符串:

代码语言:javascript
运行
复制
result = "\\footnotesize{}\\cellcolor{" + color + "}"

这并不完全是您要做的:对于值<=25,我遗漏了字符串的一部分,并且我假设所有的比较器都是>。但你明白我的意思。

票数 1
EN

Stack Overflow用户

发布于 2018-07-31 20:53:13

感谢你们的回答,对我的其他问题很有启发性和启发性。但是,我想使用字典并遍历变量名,所以我最终从@Poshi answer开始,以以下代码结束

代码语言:javascript
运行
复制
for fila in listainicial:
    ISI = ""
    mes1 = ""
    mes2 = ""
    mes3 = ""
    mes4 = ""
    mes5 = ""
    dictiocell = {"%s >= 100":"100pc", "100 > %s > 30":"masde30pc", "30 >= %s > 20":"20to30pc", "20 >= %s > 10":"10to20pc", "10 >= %s > 5":"5to10pc", "5 >= %s > 0":"0to5pc", "%s == 0":"0pc", "0 > %s > -5":"m5to0pc", "-5 >= %s > -10":"m10tom5pc", "-10 >= %s > -25":"m25tom10pc"}
    for n in range (1,6):
        for p in dictiocell:
            if eval(p %float(fila[n+2])):
                globals()["mes%s" % n] = "\\footnotesize{}\\cellcolor{" + dictiocell[p] + "}" 
        if float(fila[n+2]) <= -25:
            globals()["mes%s" % n] = "\\footnotesize{}\\cellcolor{menosdem25pc}\\color{white}"

当它工作时,我把它贴出来,因为它对这里的其他人很有帮助。

再次感谢。@reblochon,你的例子鼓舞了我在python中需要学习和改进的所有东西

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51576016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档