2014-10-01 7 views
14

Ich habe eine GUI mit wxFormBuilder erstellt, die es einem Benutzer erlauben sollte, die Namen von "Besuchern eines Unternehmens" in eine Liste einzugeben und dann auf eine der beiden Schaltflächen zu klicken häufigste und am wenigsten häufige Besucher des Geschäfts.ValueError: max() arg ist eine leere Sequenz

Ich erstellte eine frühere Version, die mir leider die Anzahl der Besucher gab, anstatt den Namen des am meisten/am wenigsten häufigen Besuchers. Ich habe einen Screenshot der GUI hinzugefügt, die ich erstellt habe, um ein wenig Klarheit in das Problem zu bringen (http://imgur.com/XJnvo0U).

Eine neue Codeversion nimmt eine andere Wende als die frühere Version, und ich kann es nicht bekommen, irgendetwas zu werfen. Stattdessen ich immer erhalten diesen Fehler:

Valueerror: max() arg eine leere Sequenz

In Bezug auf diese Zeile:

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() 
+0

Wenn 'Len (v) == 0 'ist, in' clkFindMost', 'max (v)' 'hebt ValueError'. –

Antwort

6

Da Sie immer self.listMyData auf eine leere Liste Initialisierung in clkFindMost wird Ihr Code immer zu diesem Fehler führen * weil danach sowohl unique_names als auch frequencies leere Iterables sind, also behebe das.

Eine andere Sache ist, dass, da Sie einen Satz in dieser Methode iterieren sind dann macht die Berechnung Frequenz keinen Sinn, da Satz nur eindeutige Elemente enthalten, so Häufigkeit der einzelnen Elemente ist immer 1.

Schließlich gehen sein dict.get ist eine Methode, nicht eine Liste oder Wörterbuch, so dass Sie nicht [] damit verwenden können:

richtige Weg ist:

if frequencies.get(name): 

und Pythonic Weg ist:

if name in frequencies: 

Der Pythonic Weg, um die Häufigkeit der Elemente zu erhalten ist collections.Counter zu verwenden:

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() und min() throw solche Fehler, wenn ein leerer iterable wird an sie übergeben. Sie können die Länge von v überprüfen, bevor Sie max() darauf aufrufen.

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

Wenn Sie es mit einem Iterator verwenden, dann müssen Sie zuerst den Iterator verbrauchen, bevor max() auf sie, weil boolean Wert von Iterator Aufruf immer True ist, so können wir if auf sie nicht direkt verwenden:

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

gute Nachricht ist, ausgehend von Python 3.4 Sie werden auf specify an optional return value für min() und max() bei leerer iterable können.

+0

Danke für die Erklärung. Hatte ein ähnliches Problem, als ich meine PyQt-Anwendung geschlossen und Max wurde auf einer leeren Liste aufgerufen. –

4

Wenn die Länge von v Null ist, erhalten Sie den Wert Fehler.

Sie sollten die Länge überprüfen oder Sie sollten zuerst die Liste überprüfen, ob es keine oder nicht ist.

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

oder

len(list)== 0 
Verwandte Themen