J'ai du code qui ressemble à ceci:
thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)
ok donc c'est simplifié mais vous voyez l'idée. Maintenant, il se thing
peut que ce ne soit pas réellement dans la liste, auquel cas je veux passer -1 comme thing_index
. Dans d'autres langues, c'est ce que vous vous attendez index()
à retourner s'il ne trouve pas l'élément. En fait, il jette un ValueError
.
Je pourrais faire ceci:
try:
thing_index = thing_list.index(thing)
except ValueError:
thing_index = -1
otherfunction(thing_list, thing_index)
Mais cela semble sale, en plus je ne sais pas si cela ValueError
pourrait être élevé pour une autre raison. J'ai proposé la solution suivante basée sur les fonctions du générateur, mais cela me semble un peu complexe:
thing_index = ( [(i for i in xrange(len(thing_list)) if thing_list[i]==thing)] or [-1] )[0]
Existe-t-il un moyen plus propre d'atteindre la même chose? Supposons que la liste n'est pas triée.
thing_index
." - C'est définitivement anti-pythonique. Passer une valeur de jeton (sans signification) au cas où une opération échouerait est mal vu - les exceptions sont vraiment la bonne façon ici. D'autant quething_list[-1]
c'est une expression valide, c'est-à-dire la dernière entrée de la liste.str.find
méthode qui fait exactement cela: retourne-1
lorsque l'aiguille n'est pas trouvée dans le sujet.str.index()
lève une exception si la chaîne de recherche est introuvable.Réponses:
Il n'y a rien de «sale» à utiliser la clause try-except. C'est la voie pythonique.
ValueError
sera déclenché par la.index
méthode uniquement, car c'est le seul code que vous avez là!Pour répondre au commentaire:
en Python, la philosophie plus facile de demander pardon que d'obtenir l'autorisation est bien établie, et non
index
ne soulèvera pas ce type d'erreur pour d'autres problèmes. Non pas que je puisse penser à aucun.la source
{}.get(index, '')
plus pythonique? Sans parler de plus court plus lisible.None
au lieu de -1 serait bien, mais comme vous l'avez commenté vous-même, str.find () renvoie -1 alors pourquoi n'y aurait-il pas list.find () qui fasse la même chose? Je n'achète pas l'argument "pythonique"otherfunction
. En revanche, si ce n'est pas cassé, ...Une ligne. Facile. Aucune exception.
la source
for
.indexOf = lambda item,list_ : list_.index(item) if item in list_ else -1 # OR None
Le
dict
type a uneget
fonction , où si la clé n'existe pas dans le dictionnaire, le 2ème argument deget
est la valeur qu'il doit renvoyer. De même, il y asetdefault
, qui renvoie la valeur dansdict
si la clé existe, sinon il définit la valeur en fonction de votre paramètre par défaut, puis retourne votre paramètre par défaut.Vous pouvez étendre le
list
type pour avoir unegetindexdefault
méthode.Qui pourrait alors être utilisé comme:
la source
Il n'y a rien de mal avec votre code qui utilise
ValueError
. Voici encore un autre one-liner si vous souhaitez éviter les exceptions:la source
next()
fonction existe dans Python 2.6+. Mais il est facile à implémenter pour 2.5, voir l'implémentation de la fonction next () pour Python 2.5Ce problème relève de la philosophie du langage. En Java par exemple, il y a toujours eu une tradition selon laquelle les exceptions ne devraient vraiment être utilisées que dans des «circonstances exceptionnelles», c'est-à-dire lorsque des erreurs se sont produites, plutôt que pour le contrôle de flux . Au début, c'était pour des raisons de performances, car les exceptions Java étaient lentes, mais maintenant c'est devenu le style accepté.
En revanche, Python a toujours utilisé des exceptions pour indiquer le déroulement normal du programme, comme lever un
ValueError
comme nous en discutons ici. Il n'y a rien de "sale" à ce sujet dans le style Python et il y en a beaucoup d'autres d'où cela vient. Un exemple encore plus courant est l'StopIteration
exception qui est déclenchée par lanext()
méthode d' un itérateur pour signaler qu'il n'y a pas d'autres valeurs.la source
StopIteration
car il est clairement défini ce que signifie l'exception.ValueError
est juste un peu trop générique.Si vous faites cela souvent, il est préférable de le réchauffer dans une fonction d'aide:
la source
Et ça 😃:
la source
Et ça:
Plutôt que d'exposer quelque chose d'aussi dépendant de l'implémentation comme un index de liste dans une interface de fonction, transmettez la collection et l'objet et laissez l'autre fonction gérer les problèmes de "test d'appartenance". Si une autre fonction est écrite pour être indépendante du type de collection, elle commencerait probablement par:
qui fonctionnera si thing_collection est une liste, un tuple, un ensemble ou un dict.
C'est peut-être plus clair que:
qui est le code que vous avez déjà dans une autre fonction.
la source
Et comme ça:
la source
J'ai le même problème avec la méthode ".index ()" sur les listes. Je n'ai aucun problème avec le fait qu'il lève une exception mais je ne suis pas du tout d'accord avec le fait qu'il s'agit d'une ValueError non descriptive. Je pourrais comprendre si cela aurait été une IndexError, cependant.
Je peux voir pourquoi renvoyer "-1" serait également un problème car c'est un index valide en Python. Mais de façon réaliste, je ne m'attends jamais à ce qu'une méthode ".index ()" renvoie un nombre négatif.
Voici une ligne (ok, c'est une ligne assez longue ...), parcourt la liste exactement une fois et retourne "Aucun" si l'élément n'est pas trouvé. Il serait trivial de le réécrire pour renvoyer -1, si vous le désirez.
Comment utiliser:
la source
Je ne sais pas pourquoi vous devriez penser que c'est sale ... à cause de l'exception? si vous voulez un oneliner, le voici:
mais je déconseillerais de l'utiliser; Je pense que la solution de Ross Rogers est la meilleure, utilisez un objet pour encapsuler votre comportement souhaité, n'essayez pas de pousser le langage à ses limites au détriment de la lisibilité.
la source
find()
fonction et tout sera propre;)Je suggérerais:
la source