web-dev-qa-db-fra.com

ValueError: max () arg est une séquence vide

J'ai créé une interface graphique à l'aide de wxFormBuilder qui devrait permettre à un utilisateur d'entrer les noms des "visiteurs d'une entreprise" dans une liste, puis de cliquer sur l'un des deux boutons pour renvoyer les visiteurs les plus fréquents et les moins fréquents dans l'entreprise.

J'ai créé une version antérieure qui, malheureusement, m'a donné l'éventail de visiteurs, plutôt que le nom du visiteur le plus/moins fréquent. J'ai joint une capture d'écran de l'interface graphique que j'ai créée pour aider à ajouter un peu de clarté au problème ( http://imgur.com/XJnvo ).

Une nouvelle version de code prend une approche différente de la version précédente, et je n'arrive pas à ce qu'elle lance quoi que ce soit. Au lieu de cela, je continue de recevoir cette erreur:

ValueError: max () arg est une séquence vide

Par rapport à cette ligne:

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()
24
J'onn J'onzz

Comme vous initialisez toujours self.listMyData Dans une liste vide dans clkFindMost, votre code entraînera toujours cette erreur * car après cela, unique_names Et frequencies sont vides itérables, alors corrigez cela.

Une autre chose est que, puisque vous parcourez un ensemble dans cette méthode, le calcul de la fréquence n'a aucun sens car l'ensemble ne contient que des éléments uniques, donc la fréquence de chaque élément sera toujours de 1.

Enfin, dict.get Est une méthode et non une liste ou un dictionnaire, vous ne pouvez donc pas utiliser [] Avec:

La bonne façon est:

if frequencies.get(name):

Et la voie Pythonique c'est:

if name in frequencies:

La manière Pythonique pour obtenir la fréquence des éléments est d'utiliser 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() et min() génèrent une telle erreur lorsqu'un itérable vide leur est transmis. Vous pouvez vérifier la longueur de v avant d'appeler max() dessus.

>>> 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

Si vous l'utilisez avec un itérateur, vous devez d'abord consommer l'itérateur avant d'appeler max() dessus car la valeur booléenne de l'itérateur est toujours True, nous ne pouvons donc pas utiliser if sur eux directement:

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

Les bonnes nouvelles commencent à partir de Python 3.4 vous pourrez spécifier une valeur de retour optionnelle pour min() et max() dans cas de vide itérable.

11

en une seule ligne,

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
>>> 
4

Lorsque la longueur de v sera nulle, cela vous donnera l'erreur de valeur.

Vous devez vérifier la longueur ou vérifier d'abord la liste, qu'elle soit nulle ou non.

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

ou

len(list)== 0
4
Aamish Baloch