ValueError: max() arg - пустая последовательность

Я создал графический интерфейс с использованием wxFormBuilder, который должен позволить пользователю вводить имена "посетителей в бизнес" в список, а затем щелкнуть одну из двух кнопок, чтобы возвращать наиболее частых и наименее частых посетителей в бизнес.

Я создал более раннюю версию, которая, к сожалению, дала мне диапазон посетителей, а не имя самого/наименее частого посетителя. Я добавил скриншот графического интерфейса, который я создал, чтобы помочь добавить немного ясности в проблему (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()

Ответы

Ответ 1

Поскольку вы всегда инициализируете self.listMyData пустым списком в clkFindMost ваш код всегда будет приводить к этой ошибке *, потому что после этого и unique_names и frequencies являются пустыми итерабельными, поэтому исправьте это.

Другое дело, что, поскольку вы выполняете итерацию по набору в этом методе, тогда вычисление частоты не имеет смысла, поскольку набор содержит только уникальные элементы, поэтому частота каждого элемента всегда будет равна 1.

Наконец, dict.get - это метод, а не список или словарь, поэтому вы не можете использовать []:

Правильный способ:

if frequencies.get(name):

И Путинский путь:

if name in frequencies:

Питоновский способ получить частоту элементов - использовать 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, поэтому мы не можем использовать, if на них напрямую:

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

Хорошая новость начинается с Python 3.4, вы можете указать необязательное возвращаемое значение для min() и max() в случае пустой итерации.

Ответ 2

Когда длина v будет равна нулю, она даст вам ошибку значения.

Вы должны проверить длину или сначала проверить список, нет ли этого или нет.

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

или

len(list)== 0

Ответ 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
>>>