Pourquoi la liste n'a-t-elle pas une méthode sûre "get" comme le dictionnaire?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
Pourquoi la liste n'a-t-elle pas une méthode sûre "get" comme le dictionnaire?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
l[10:11]
au lieu del[10]
, par exemple. () La sous-liste aura l'élément souhaité s'il existe).get
. Ce serait l'équivalentl[i] if i < len(l) else default
, mais plus lisible, plus concis, et permettanti
d'être une expression sans avoir à la recalculerNone
s'il n'en existait pas. Cela aurait été bien de direx = expensive().get(0, None)
que je n'aurais pas à mettre le retour inutile de cher dans une variable temporaire.Réponses:
En fin de compte, il n'a probablement pas de
.get
méthode sûre car adict
est une collection associative (les valeurs sont associées aux noms) où il est inefficace de vérifier si une clé est présente (et de renvoyer sa valeur) sans lever d'exception, alors qu'elle est super triviale pour éviter les exceptions d'accès aux éléments de la liste (car lalen
méthode est très rapide). La.get
méthode vous permet d'interroger la valeur associée à un nom, et non d'accéder directement au 37e élément du dictionnaire (ce qui ressemblerait davantage à ce que vous demandez à votre liste).Bien sûr, vous pouvez facilement l'implémenter vous-même:
Vous pouvez même le monkeypatch sur le
__builtins__.list
constructeur dans__main__
, mais ce serait un changement moins répandu car la plupart du code ne l'utilise pas. Si vous souhaitez simplement l'utiliser avec des listes créées par votre propre code, vous pouvez simplement souslist
- classer et ajouter laget
méthode.la source
list
.get
résout un problème que les listes n'ont pas - un moyen efficace d'éviter les exceptions lors de l'obtention de données qui peuvent ne pas exister. Il est super trivial et très efficace de savoir ce qu'est un index de liste valide, mais il n'y a aucun moyen particulièrement bon de le faire pour les valeurs clés dans un dictionnaire.O(1)
. Ce ne sera pas aussi rapide en termes bruts que la vérificationlen
, mais d'un point de vue complexité, ils sont tousO(1)
. La bonne réponse est celle typique d'utilisation / sémantique ...dict
seul le meilleur cas est O (1), pas tous les cas..get()
ou vous avez des problèmes ailleurs dans votre code (ou environnement). L'intérêt d'une telle méthode est la lisibilité du code. La technique "vanille" nécessite quatre lignes de code à chaque endroit que cela doit être fait. La.get()
technique n'en nécessite qu'un et peut facilement être enchaînée avec des appels de méthode ultérieurs (par exemplemy_list.get(2, '').uppercase()
).Cela fonctionne si vous voulez le premier élément, comme
my_list.get(0)
Je sais que ce n'est pas exactement ce que vous avez demandé, mais cela pourrait aider les autres.
la source
next(iter(my_list[index:index+1]), 'fail')
Permet de tout indice, non seulement 0. Ou moins FP , mais sans doute plus Pythonic, et presque certainement plus facile à lire:my_list[index] if index < len(my_list) else 'fail'
.Probablement parce que cela n'avait tout simplement pas beaucoup de sens pour la sémantique des listes. Cependant, vous pouvez facilement créer le vôtre en sous-classant.
la source
get
méthode. La lisibilité compte. Et la lisibilité souffre avec chaque classe supplémentaire inutile. Utilisez simplement l'try / except
approche sans créer de sous-classes.Au lieu d'utiliser .get, une utilisation comme celle-ci devrait être correcte pour les listes. Juste une différence d'utilisation.
la source
.get
méthode (sauf que je ne sais pas comment vous expliqueriez ce que l'index signifiait dans ce cas, ni pourquoi il échouerait).lst[i] if -len(lst) <= i < len(l) else 'fail'
Essaye ça:
la source
Crédits à jose.angel.jimenez
Pour les fans "oneliner"…
Si vous voulez le premier élément d'une liste ou si vous voulez une valeur par défaut si la liste est vide, essayez:
Retour
a
et
Retour
default
Exemples pour d'autres éléments…
Avec repli par défaut…
Testé avec
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
la source
value, = liste[:1] or ('default',)
. Il semble que vous ayez besoin des parenthèses.La meilleure chose que vous puissiez faire est de convertir la liste en dict, puis d'y accéder avec la méthode get:
la source
zip range len
chose, on pourrait simplement utiliserdict(enumerate(my_list))
J'ai donc fait des recherches supplémentaires à ce sujet et il s'avère qu'il n'y a rien de spécifique à cela. Je me suis excité quand j'ai trouvé list.index (valeur), il renvoie l'index d'un élément spécifié, mais il n'y a rien pour obtenir la valeur à un index spécifique. Donc, si vous ne voulez pas utiliser la solution safe_list_get qui, je pense, est plutôt bonne. Voici quelques instructions qui peuvent faire le travail pour vous selon le scénario:
Vous pouvez également utiliser None au lieu de 'No', ce qui est plus logique .:
De plus, si vous souhaitez simplement obtenir le premier ou le dernier élément de la liste, cela fonctionne
Vous pouvez également en faire des fonctions, mais j'ai toujours aimé la solution d'exception IndexError. J'ai expérimenté avec une version factice de la
safe_list_get
solution et je l'ai rendue un peu plus simple (pas de défaut):Je n'ai pas de référence pour voir ce qui est le plus rapide.
la source
list
en le sous- classant . De cette façon, le constructeur peut prendre unlist
ou tout ce qui se comporte comme une liste, et la nouvelle instance se comporte comme unlist
. Voir la réponse de Keith ci-dessous qui devrait être celle acceptée à mon humble avis.dict.get()
renvoyer une valeur par défaut à partir d'une référence d'index de liste au lieu d'avoir à intercepterIndexError
? Il s'agit donc vraiment de la fonction de langue / bibliothèque (et non de POO Contexte FP) De plus, il faut probablement qualifier votre utilisation de 'pythonic' comme peut-être WWGD (comme son dédain pour FP Python est bien connu) et pas nécessairement satisfaisant juste PEP8 / 20.el = x[4] if len(x) == 4 else 'No'
- tu veux direlen(x) > 4
?x[4]
est hors limites silen(x) == 4
.Les dictionnaires sont destinés aux recherches. Il est logique de demander si une entrée existe ou non. Les listes sont généralement itérées. Il n'est pas courant de demander si L [10] existe mais plutôt si la longueur de L est 11.
la source
Votre cas d'utilisation n'est fondamentalement pertinent que lorsque vous effectuez des tableaux et des matrices de longueur fixe, afin que vous sachiez combien de temps ils sont avant la main. Dans ce cas, vous les créez généralement avant de les remplir manuellement avec None ou 0, de sorte qu'en fait, tout index que vous utiliserez existe déjà.
On pourrait dire ceci: j'ai souvent besoin de .get () dans les dictionnaires. Après dix ans en tant que programmeur à temps plein, je ne pense pas en avoir jamais eu besoin sur une liste. :)
la source
'lalala' in url.split('/')[2:]
. Mais le problème avec votre solution ici est que vous ne regardez que le deuxième élément. Que faire si l'URL est '/ monkeybonkey / lalala'? Vous obtiendrez unTrue
même si l'URL n'est pas valide.