我有一个脚本,转换成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}"
从fila1到fila4重复执行该代码
这太不自然了,让我觉得有点下流。我的脚本工作和复制块不是问题,但正如我在标题中指出的那样,我希望生成更优雅和令人满意的代码。
我真的很想用一本字典来代替这种冗长而单调的if...elif系列。我也会感谢任何其他的解决方案,以减少我的110行的脚本长的部分。
我真的很感激在这方面的任何提示或解决方案
提前感谢
发布于 2018-07-29 09:09:13
这是我试图封装你的代码,让它不那么笨拙:
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}']
发布于 2018-07-29 08:26:02
您可以定义(limit,color)的元组的排序列表:
colors = [(-25,'menosdem25pc'), (-10, 'm25tom10pc'), (-5, 'm10tom5pc')...]
然后,您可以过滤搜索以查找感兴趣的内容:
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]
现在,您可以编写字符串:
result = "\\footnotesize{}\\cellcolor{" + color + "}"
这并不完全是您要做的:对于值<=25,我遗漏了字符串的一部分,并且我假设所有的比较器都是>
。但你明白我的意思。
发布于 2018-07-31 20:53:13
感谢你们的回答,对我的其他问题很有启发性和启发性。但是,我想使用字典并遍历变量名,所以我最终从@Poshi answer开始,以以下代码结束
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中需要学习和改进的所有东西
https://stackoverflow.com/questions/51576016
复制相似问题