python - 寻找pythonic的优雅:字典而不是重复的意大利面条块
问题描述
我有一个将嵌套列表转换为 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]]
我脚本的那部分是这样的
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}"
代码从fila[1] 到fila[4] 重复
这太不合情理了,我觉得有点脏。我的脚本有效,复制粘贴块不是问题,但正如我在标题中指出的那样,我想生成更优雅和令人满意的代码。
我真的很想用字典代替如此冗长而单调的 if...elif 系列。我也将不胜感激任何其他解决方案,它可以减少我的 110 行长的脚本部分。
在这个意义上,我真的很感激任何提示或解决方案
提前致谢
解决方案
这是我尝试封装您的代码并使其不那么笨拙的尝试:
上面的所有if name == main
内容都可以提取到一个单独的模块中,使您的主要代码如下所示:
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)
我添加了文档字符串来解释每个类/方法的作用;如果需要更多解释,请告诉我。
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)
输出:
['\\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}']
推荐阅读
- java - Apache CachingHttpClientBuilder 的默认缓存行为是什么?
- excel - 在excel中求和产品动态范围
- c# - 希望将所有对象列表组合成单个字符串
- reactjs - 嵌套地图中的反应功能组件多次重新渲染
- google-apps-script - Google 表格查询功能 - 如何引用活动表格/标签名称?
- html - 如何摆脱侧滚动条
- html - 无法在 NativeScript 的 TextField 中更改字体
- python - 在 python 中升级 pytesseract
- c# - C#是否有一个选项可以查看文件更改而不在更改事件后重新打开它
- visual-studio-code - VScode - 无法恢复正常的移位箭头选择