ValueError:max()arg是一个空序列

时间:2014-10-01 22:22:31

标签: python list for-loop

我使用wxFormBuilder创建了一个GUI,允许用户输入"商家访客的名字。进入列表,然后单击两个按钮之一,以返回业务中最频繁和最不频繁的访问者。

我创建了一个早期版本,不幸的是,它给了我一系列访问者,而不是最常/最不常访问者的名字。我附上了我创建的GUI的屏幕截图,以帮助为问题添加一些清晰度(http://imgur.com/XJnvo0U)。

新的代码版本与早期版本的版本不同,我无法抛出任何东西。相反,我一直收到这个错误:

ValueError:max()arg是一个空序列

关于这一行:

self.txtResults.Value = k.index(max(v))

import wx
import myLoopGUI
import commands

class MyLoopFrame(myLoopGUI.MyFrame1):
    def __init__(self, parent):
        myLoopGUI.MyFrame1.__init__(self, parent)

    def clkAddData(self,parent):
        if len(self.txtAddData.Value) != 0:
            try:
                myname = str(self.txtAddData.Value)
                self.listMyData.Append(str(myname))
            except:
                wx.MessageBox("This has to be a name!")            
        else:
            wx.MessageBox("This can't be empty")




    def clkFindMost(self, parent):
        self.listMyData = []
        unique_names = set(self.listMyData)
        frequencies = {}
        for name in unique_names:
            if frequencies.get[name]:
                frequencies[name] += 1
            else:
                frequencies[name] = 0

        v = list(frequencies.values())
        k = list(frequencies.keys())
        self.txtResults.Value = k.index(max(v))


    def clkFindLeast(self, parent):
        unique_names = set(self.listMyData)
        frequencies = {}
        for name in unique_names:
            if frequencies.get(name):
                frequencies[name] += 1
            else:
                frequencies[name] = 0

        v = list(frequencies.values())
        k = list(frequencies.keys())
        self.txtResults.Value = k.index(min(v))

myApp = wx.App(False)
myFrame = MyLoopFrame(None)
myFrame.Show()
myApp.MainLoop()

4 个答案:

答案 0 :(得分:10)

由于您始终将self.listMyData初始化为clkFindMost中的空列表,因此您的代码将始终导致此错误*因为此后unique_namesfrequencies都是空的迭代,所以解决这个问题。

另一件事是,由于您在该方法中迭代一组,因此计算频率没有意义,因为集合仅包含唯一项目,因此每个项目的频率始终为1。

最后,dict.get是一种方法而非列表或字典,因此您无法使用[]

正确的方法是:

if frequencies.get(name):

而Pythonic的方式是:

if name in frequencies:

获取项目频率的Pythonic方法是使用collections.Counter

from collections import Counter   #Add this at the top of file.

def clkFindMost(self, parent):

        #self.listMyData = []   
        if self.listMyData:
           frequencies = Counter(self.listMyData)
           self.txtResults.Value = max(frequencies, key=frequencies.get)
        else:
           self.txtResults.Value = '' 

max()min()在向它们传递空迭代时抛出此类错误。您可以在调用v之前检查max()的长度。

>>> lst = []
>>> max(lst)

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    max(lst)
ValueError: max() arg is an empty sequence
>>> if lst:
    mx = max(lst)
else:
    #Handle this here

如果你将它与迭代器一起使用,那么你需要首先使用迭代器,然后在它上面调用max(),因为迭代器的布尔值总是True,所以我们不能使用{{1直接在他们身上:

if

好消息是从Python 3.4开始,如果空可迭代,你可以>>> it = iter([]) >>> bool(it) True >>> lst = list(it) >>> if lst: mx = max(lst) else: #Handle this here min()max()

答案 1 :(得分:3)

在一行中,

v = max(v) if v else None

>>> v = []
>>> max(v)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence
>>> v = max(v) if v else None
>>> v
>>> 

答案 2 :(得分:2)

尝试解析默认值,如果v的长度为none,则默认值可以返回

max(v, default=0)

答案 3 :(得分:0)

我意识到我正在遍历一个列表列表,其中一些列表为空。我通过添加以下预处理步骤来解决此问题:

tfidfLsNew = [x for x in tfidfLs if x != []]

原件的len()为3105,后者的len()为3101,这意味着我的四个列表完全为空。进行此预处理后,我的max()min()等再次起作用。