代码之家  ›  专栏  ›  技术社区  ›  Community wiki

使用tkinter-Scale窗口小部件数据进行列表理解

  •  0
  • Community wiki  · 技术社区  · 2 年前

    我正试图创建一个python 2.7 tkinter模块,该模块使用比例小部件数据来影响列表理解,该列表理解在概率特征表示为列表的动物之间进行选择。点击“提交”并激活相关命令后,模块会按降序对三只动物进行排序和显示。

    在这个例子中,三只动物在点击“提交”后都达到了33%,因为它们共享相同的概率数据。这些动物在列表列表的第2列中的比例小部件数据之间的不同之处在于,每种动物要么是水生的,要么是陆地的,或者两者都是。

    from Tkinter import BOTH, BOTTOM, Button, E, END, Entry, FLAT, Frame, Grid, HORIZONTAL, Label, LEFT, N, NO, Pack, RAISED, RIGHT, S, Scale, Text, Tk, TOP, W, YES
    
    from operator import mul
    
    root = Tk()
    root.title('Example')
    
    class Environment:
        def __init__(self, parent):
    
            # layout
            self.myParent = parent
    
            self.main_frame = Frame(parent, background="light blue")
            self.main_frame.pack(expand=YES, fill=BOTH)
    
            self.main_left_frame = Frame(self.main_frame, background="light blue")
            self.main_left_frame.pack(side=LEFT, expand=YES, fill=BOTH)
    
            self.main_right_frame = Frame(self.main_frame, background="light blue")
            self.main_right_frame.pack(side=RIGHT, expand=YES, fill=BOTH)
    
            self.water = Scale(self.main_right_frame, from_=0.01, to=1.00, orient=HORIZONTAL, bd=0, label="Aquatic",
            background="white", troughcolor="cyan", length=50, width=10, sliderlength=10, resolution=0.01)
            self.water.pack()
            self.water.set(1.00)
    
            self.soil = Scale(self.main_right_frame, from_=0.01, to=1.00, orient=HORIZONTAL, bd=0, label="Terrestrial",
            background="white", troughcolor="saddle brown", length=50, width=10, sliderlength=10, resolution=0.01)
            self.soil.pack()
            self.soil.set(1.00)
    
            self.id_frame = Frame(self.main_left_frame, background="white")
            self.id_frame.pack(side=BOTTOM)
    
            # submit button
            self.submitbutton = Button(self.main_left_frame,text="Submit", background="black", foreground="white",
            width=6, padx="2m", pady="1m")
            self.submitbutton.pack(side=TOP)
            self.submitbutton.bind("<Button-1>", self.submitbuttonclick)
            self.submitbutton.bind("<Return>", self.submitbuttonclick)
    
            #Animal Matrix
            self.animal = [
            ('Odocoileous virginiana','White-tailed Deer',self.soil.get,0.99,0.01,0.99),
            ('Anguilla anguilla','American Eel',self.water.get,0.99,0.01,0.99),
            ('Trachemys scripta','Slider',lambda:self.soil.get()*self.water.get(),0.99,0.01,0.99)]
    
        def submitbuttonclick(self, event):
            self.id_frame.destroy()
            self.id_frame = Frame(self.main_left_frame, background="white")
            self.id_frame.pack(side=BOTTOM)
    
            A=self.animal
    
            #equation
            sigma = float(sum(reduce(mul,item[3:]) for item in A))
            B = [(item[0], "%.2f" % (item[2]()*reduce(mul, item[3:])/sigma)) for item in A]
            C = sorted(B, key=lambda item: item[1], reverse=True)  
    
            Label(self.id_frame, text = C[0], background = "white").pack(side=TOP, anchor = W)
            Label(self.id_frame, text = C[1], background = "white").pack(side=TOP, anchor = W)
            Label(self.id_frame, text = C[2], background = "white").pack(side=TOP, anchor = W)
    
    environment = Environment(root)       
    root.mainloop()
    

    由于许多贡献的改进,此代码可以工作!

    3 回复  |  直到 6 年前
        1
  •  0
  •   senderle    13 年前

    我注意到的第一件事是你定义了 A 为空字典,然后用覆盖该空字典 self.animal ,这是一个列表。

        A={}
        A=self.animal
    

    所以我不知道你在这里是什么意思。那么在你对 B 你把它切开:

        B = [(A[0], "%.2f" % (reduce(mul,A[3:])*A[2][i]/sigma*A[2][i])) for A in A]
    

    这与 任何一个 的定义 A. ,因为你不能对dict进行切片,但你选择的起始索引是 3 ,中的最高索引 自动 2 令人困惑但仔细观察,问题很明显是你在重复使用 A. 作为索引变量。你 真正地 不应该那样做;它生成了这个代码 难以置信地 令人困惑

    它也可能导致错误。请考虑以下代码:

    >>> a = range(10)
    >>> [a for a in a]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> a
    9
    

    正如你所看到的,列表理解导致 a 引用之前已知的序列中的最后一个值 。这不会在您的代码中发生,因为您使用了生成器表达式。但它仍然很难阅读和混淆。我 强烈地 建议改为执行以下操作:

        sigma = float(sum(reduce(mul,item[3:]) for item in A))
        B = [(item[0], "%.2f" % (reduce(mul,item[3:])/sigma)) for item in A] 
    

    使现代化 :好的,做了这些改变后,你仍然需要 get 来自天平的数据。在你对 自动 ,您使用 self.soil.get() ,就像这样:

    ('Odocoileous virginiana','White-tailed Deer',self.soil.get(),0.99,0.01,0.99)
    

    这使得的返回值 self.土壤.get() 在元组中。但这个值是固定的——永远不会改变。你必须明确地调用 self.土壤.get() 每次 您需要更新的值。此外,您的列表理解永远不会访问返回的值。你这样切开它们:

    >>> l = ('Odocoileous virginiana','White-tailed Deer',
    ...      self.soil.get(), 0.99, 0.01, 0.99)
    >>> l[3:]
    (0.98999999999999999, 0.01, 0.98999999999999999)
    

    请记住,列表和元组中的索引以 0 --所以在上面的元组中 l , l[0] == 'Odocoileous virginiana' 。因此,如果您想要除前两项之外的所有内容,则必须从索引2进行切片:

    >>> l[2:]
    (0.55000000000000004, 0.98999999999999999, 0.01, 0.98999999999999999)
    

    但这仍然不能解决根本问题,那就是你必须打电话 self.土壤.get() 以获得更新的数据。你可以做到这一点的一种方法就是简单地重新创造 自动 每次点击提交按钮时。这将是浪费,但它会起作用。一种不那么浪费(但仍然很尴尬)的方法是将函数本身保存在元组中,而不是保存函数的结果。你会这样做的:

    >>> l = ('Odocoileous virginiana','White-tailed Deer',
    ...      self.soil.get, 0.99, 0.01, 0.99)
    

    注意没有 () 之后 self.soil.get 。现在元组包含的不是浮点值,而是一个返回浮点值的函数。您必须调用它才能获得值,但它每次都会返回完全更新的值。要组合函数,可以使用 lambda 以下为:

    >>> l = ('Odocoileous virginiana','White-tailed Deer',
    ...      lambda: self.soil.get() * self.water.get(), 0.99, 0.01, 0.99)
    

    现在你可以打电话 l[2] 要获得一个值:

    >>> l[2]()
    0.30250000000000005
    

    因此,为了把所有这些放在一起,你必须进一步分解列表理解,才能明确地调用 l[2] ,但一旦你做到了,这应该会奏效。这不是一个理想的设置,但恐怕我不得不把创建一个改进的体系结构作为读者的练习。

        2
  •  0
  •   platinummonkey    13 年前

    A[2][i]/sigma*A[2][i] 此位正在尝试对浮点进行索引。 应该是: A[i]/sigma*A[i] 相反

    我确实假设了A中的值都是浮点值。

        3
  •  0
  •   dr. Sybren    13 年前

    这个 for A in A 这个部分在我看来有点不可靠。它可能在语法上是正确的,但通常对集合和这些集合中的元素使用不同的名称会更清楚。

    而且 for isolates in A: i = A.index(isolates) 可以通过使用 for i, isolates in enumerate(A) A.index(isolates) 当a很大的时候可能需要很长时间。

    我知道,这并不是你问题的真正答案,但我希望它仍然有用。

    为了更容易调试(并实际帮助您),请重写以下内容:

    [(A[0], "%.2f" % (reduce(mul,A[3:])*A[2][i]/sigma*A[2][i])) for A in A]

    变成可读性更强的东西。如果你用多行把它拆分成一些东西,你实际上可以使用调试器,很容易地看到什么变量是“float”,以及它在哪里被索引。