ValueError: max() arg is een lege reeks

Ik heb een GUI gemaakt met behulp van wxFormBuilder waarmee een gebruiker de namen van “bezoekers aan een bedrijf” in een lijst moet invoeren en vervolgens op een van de twee knoppen moet klikken om de meest frequente en minst frequente bezoekers naar het bedrijf terug te sturen.

Ik heb een eerdere versie gemaakt die me helaas het bereik van bezoekers gaf, in plaats van de naam van de meest/minst frequente bezoeker. Ik heb een screenshot bijgevoegd van de GUI die ik heb gemaakt om het probleem wat duidelijker te maken ( http://imgur.com/XJnvo0U).

Een nieuwe codeversie pakt het anders aan dan de eerdere versie, en ik kan er niets mee doen. In plaats daarvan krijg ik steeds deze foutmelding:

ValueError: max() arg is een lege reeks

Met betrekking tot deze regel:

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

Antwoord 1, autoriteit 100%

Geef een defaultwaarde door die kan worden geretourneerd door maxals de reeks leeg is:

max(v, default=0)

Antwoord 2, autoriteit 77%

Omdat je altijd self.listMyDatainitialiseert naar een lege lijst in clkFindMost, zal je code altijd tot deze fout leiden* omdat daarna beide unique_namesen frequencieszijn lege herhalingen, dus los dit op.

Een ander ding is dat aangezien je in die methode een set itereert, het berekenen van de frequentie geen zin heeft, omdat een set alleen unieke items bevat, dus de frequentie van elk item zal altijd 1 zijn.

Ten slotte is dict.geteen methode, geen lijst of woordenboek, dus je kunt er []niet mee gebruiken:

De juiste manier is:

if frequencies.get(name):

En Pythonische manier is:

if name in frequencies:

De Python-manier om de frequentie van items te krijgen, is door 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()en min()geven zo’n fout wanneer er een lege iterable aan hen wordt doorgegeven. Je kunt de lengte van vcontroleren voordat je max()erop aanroept.

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

Als je het met een iterator gebruikt, moet je eerst de iterator gebruiken voordat je max()erop aanroept, omdat de booleaanse waarde van de iterator altijd Trueis, dus we kunnen ifer niet rechtstreeks op gebruiken:

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

Goed nieuws: vanaf Python 3.4 kun je specificeer een optionele retourwaardevoor min()en max()in het geval van lege iterable.


Antwoord 3, autoriteit 27%

Als de lengte van v nul is, krijg je de waardefout.

U moet de lengte controleren of u moet eerst de lijst controleren of deze geen of niet is.

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

of

len(list)== 0

Antwoord 4, autoriteit 23%

in één regel,

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

Antwoord 5

Ik realiseerde me dat ik een lijst met lijsten aan het herhalen was waarvan sommige leeg waren. Ik heb dit opgelost door deze voorbewerkingsstap toe te voegen:

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

de len() van het origineel was 3105, en de len() van de laatste was 3101, wat inhoudt dat vier van mijn lijsten helemaal leeg waren. Na dit voorproces functioneerden mijn max() min() enz. weer.

Other episodes