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