【问题标题】:Python: How to refer to optional variables without errorPython:如何在没有错误的情况下引用可选变量
【发布时间】:2013-10-12 06:01:02
【问题描述】:

我正在尝试为具有可变数据集的图创建图例。至少有 2 个,最多 5 个。前两个将一直存在,但其他三个是可选的,那么如何仅为现有数量的数据集创建图例?

我已经尝试过 if 语句来告诉 python 如果该变量不存在该怎么办,但没有用。也许这不是确定变量存在的正确方法。

line1 = os.path.basename(str(os.path.splitext(selectedFiles[0])[0]))
line2 = os.path.basename(str(os.path.splitext(selectedFiles[1])[0]))

if selectedFiles[2] in locals:
    line3 = os.path.basename(str(os.path.splitext(selectedFiles[2])[0]))
else: line3 = None

if selectedFiles[3] in locals:
    line4 = os.path.basename(str(os.path.splitext(selectedFiles[3])[0]))
else: line4 = None

if selectedFiles[4] in locals:
    line5 = os.path.basename(str(os.path.splitext(selectedFiles[4])[0]))
else:line5 = None

legend((line1, line2, line3, line4, line5), loc='upper left')

这是我得到的错误:

     if selectedFiles[2] in locals:
IndexError: tuple index out of range

他的代码可能存在多个问题(不确定“无”是否是处理不存在数据的正确方法)。请记住,我是 python 新手,没有什么编程经验,所以请耐心等待,不要屈尊俯就,因为一些更有经验的用户往往会这样做。

【问题讨论】:

  • 你是如何创建selectedFiles的?
  • 答案通常有正确的想法,但我很好奇locals 是如何定义的。 locals() 是一个内置函数,它返回本地符号表,一个将变量名称映射到其关联对象的字典。如果您没有在本地绑定名称,in locals 将引发异常,因为 in 运算符不适用于函数。 in locals() 在语法上是正确的,但不是您在检查数组元素是否存在时想要的。除非您的数组包含作为局部变量名称的字符串。
  • 到目前为止,我很高兴看到我的问题至少部分可以理解。 @thefourtheye selectedFiles 是使用 Tkinter 的对话框窗口创建的:'selectedFiles = tkFileDialog.askopenfilenames(parent=rt,title='Choose a file') selectedFiles = rt.tk.splitlist(selectedFiles)'
  • @PeterDeGlopper,我现在明白我以两种方式错误地使用了“本地人”。下面的答案与我正在寻找的答案很接近。

标签: python variables plot legend optional


【解决方案1】:

因为 selectedFiles 是一个元组,里面处理每一项的逻辑都是一样的。您可以使用 for 循环对其进行迭代。

lines = [os.path.basename(str(os.path.splitext(filename)[0])) for filename in selectedFiles]

#extend lines' length to 5 and fill the space with None
lines = lines + [None] * (5-len(lines))

legend(lines,loc='upper left')

【讨论】:

  • @PeterDeGlopper 为什么?根据示例代码,legend() 的第一个参数是一个可迭代对象。
  • 我删除了线条的第二个定义,因为它在图例上给了我 3 个“无”。否则这是完美的!
【解决方案2】:

我不知道你的数据结构是什么样的,但看起来你只是想要

lines = (os.path.basename(str(os.path.splitext(x)[0])) for x in selectedFiles)

legend(lines, loc='upper left')

【讨论】:

  • 打败我。请特别参阅 docs.python.org/2/tutorial/… 以获取有关 *lines 发生情况的文档。但是括号的平衡与 OP 的版本不同,所以虽然方法是正确的,但精确的语法可能是错误的。
  • @PeterDeGlopper 指出。我已经重新校准了括号中的天平。
  • “行”之前不需要“*”。这使传说混淆,以为我想要其中一个文件标题作为位置。
【解决方案3】:

我更喜欢这种方式。

line = []

for i in range(5):
  if i < len(selectedFiles):
    line.append(os.path.basename(str(os.path.splitext(selectedFiles[i])[0])))
  else:
    line.append(None)

legend(tuple(line), loc='upper left')

或者您可以随时使用except IndexError:

【讨论】:

  • 仅出于代码高尔夫的目的,如果我需要用 None 填充元组并且不想使用 glasslion 的解决方案:tuple(itertools.islice(itertools.chain(os.path.basename(...) for x in selectedFiles, itertools.repeat(None)), 5))
猜你喜欢
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 2018-03-27
相关资源
最近更新 更多