【问题标题】:ValueError: max() arg is an empty sequenceValueError: max() arg 是一个空序列
【发布时间】:2014-11-26 21:38:40
【问题描述】:

我已经使用 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()

【问题讨论】:

  • len(v) == 0,在clkFindMostmax(v) 引发ValueError
  • 当您在 max() 中传递空列表时会出现这种类型的错误。所以检查列表是否可用,而不是将其传递给最大值

标签: python list for-loop


【解决方案1】:

传递一个default 值,如果序列为空,max 可以返回该值:

max(v, default=0)

【讨论】:

  • 这对我很有帮助。
  • 这个解决方案对我很有帮助。
  • 在 3 上工作,但 python 2 中的 max 没有 default 参数
  • 如果您知道 v 没有 None 项目,这很不错。否则你会收到一个错误:TypeError: '>' not supported between instances of 'NoneType' and 'int'
【解决方案2】:

我意识到我正在遍历一个列表列表,其中一些列表是空的。我通过添加这个预处理步骤解决了这个问题:

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

原来的 len() 是 3105,而后者的 len() 是 3101,这意味着我的四个列表完全是空的。在这个预处理之后,我的 max() min() 等再次运行。

【讨论】:

    【解决方案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
    >>> 
    

    【讨论】:

    • 我经常这样做max(seq or [0]),如果序列为空,则默认返回0。
    • 如果 max([0]) 为 0,你想要什么?如果你不想再添加一个如果v = max(v) if v else None if not max(v) else None
    • 我不确定我是否理解这个问题。仅当我希望默认值为零时才使用max(seq or [0]),即如果我在算术运算中使用结果。如果我希望默认为无,我会使用max(seq) if seq else None
    【解决方案4】:

    当 v 的长度为零时,它会给你值错误。

    你应该检查长度,或者你应该先检查列表是否没有。

    if list:
        k.index(max(list))
    

    len(list)== 0
    

    【讨论】:

      【解决方案5】:

      由于您始终将 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() 在将空的可迭代对象传递给它们时会抛出此类错误。您可以在调用max() 之前检查v 的长度。

      >>> 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,因此我们不能直接在它们上使用if

      >>> it = iter([])
      >>> bool(it)
      True
      >>> lst = list(it)
      >>> if lst:
             mx = max(lst)
          else:
            #Handle this here   
      

      好消息是从 Python 3.4 开始,您将能够 specify an optional return value 获取 min()max(),以防可迭代对象为空。

      【讨论】:

      • 感谢您的解释。当我关闭我的 PyQt 应用程序并且在一个空列表上调用 max 时遇到了类似的问题。
      猜你喜欢
      • 2016-07-03
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 2018-06-29
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多