En C #, il y a un opérateur de coalescence nulle (écrit comme ??
) qui permet une vérification nulle (courte) facile pendant l'affectation:
string s = null;
var other = s ?? "some default value";
Existe-t-il un équivalent python?
Je sais que je peux faire:
s = None
other = s if s else "some default value"
Mais y a-t-il un chemin encore plus court (où je n'ai pas besoin de répéter s
)?
python
null-coalescing-operator
Klaus Byskov Pedersen
la source
la source
??
opérateur est proposé comme PEP 505 .Réponses:
Ok, il faut clarifier le fonctionnement de l'
or
opérateur. Il s'agit d'un opérateur booléen, il fonctionne donc dans un contexte booléen. Si les valeurs ne sont pas booléennes, elles sont converties en booléennes pour les besoins de l'opérateur.Notez que l'
or
opérateur ne retourne pas seulementTrue
ouFalse
. Au lieu de cela, il renvoie le premier opérande si le premier opérande est évalué à vrai et il renvoie le deuxième opérande si le premier opérande est évalué à faux.Dans ce cas, l'expression
x or y
retournex
si elle estTrue
ou est évaluée à true lorsqu'elle est convertie en booléen. Sinon, il revienty
. Dans la plupart des cas, cela servira aux mêmes fins que l'opérateur de coalescence nulle de C♯, mais gardez à l'esprit:Si vous utilisez votre variable
s
pour contenir quelque chose qui est soit une référence à l'instance d'une classe ouNone
(tant que votre classe ne définit pas de membres__nonzero__()
et__len__()
), il est sûr d'utiliser la même sémantique que l'opérateur de coalescence nulle.En fait, il peut même être utile d'avoir cet effet secondaire de Python. Étant donné que vous savez quelles valeurs sont évaluées comme fausses, vous pouvez l'utiliser pour déclencher la valeur par défaut sans utiliser
None
spécifiquement (un objet d'erreur, par exemple).Dans certaines langues, ce comportement est appelé opérateur Elvis .
la source
s
c'est une valeur valide mais n'est-ce pas vrai? (Je ne connais pas Python, donc je ne sais pas si le concept de `` véridique '' s'applique.)None
et les conteneurs vides (y compris les chaînes) sont considérés comme faux, en plus de la constanteFalse
. Presque tout le reste est considéré comme vrai. Je dirais que le principal danger ici serait que vous obteniez une valeur vraie mais non chaîne, mais ce ne sera pas un problème dans certains programmes.datetime.time(0)
c'était aussi faux!Strictement,
Sinon,
s = False
deviendra"default value"
, ce qui peut ne pas être ce qui était prévu.Si vous souhaitez raccourcir ce délai, essayez:
la source
Consider x()?.y()?.z()
Voici une fonction qui renverra le premier argument qui ne l'est pas
None
:reduce()
pourrait itérer inutilement sur tous les arguments même si le premier argument ne l'est pasNone
, vous pouvez donc également utiliser cette version:la source
def coalesce(*arg): return next((a for a in arg if a is not None), None)
fait la même chose que votre dernier exemple sur une ligne.Consider x()?.y()?.z()
Je sais que c'est répondu, mais il existe une autre option lorsque vous traitez avec des objets.
Si vous avez un objet qui pourrait être:
Vous pouvez utiliser:
Comme:
En ajoutant
{}
comme valeur par défaut, si "nom" est manquant, un objet vide est retourné et transmis à la prochaine get. Ceci est similaire à la navigation null-safe en C #, ce qui serait commeobj?.name?.first
.la source
.get
, cela ne fonctionne que pour les objets de type dictgetattr()
également.get
on dict n'utilise pas le paramètre par défaut si la valeur est None mais utilise le paramètre par défaut si la valeur n'existe pas car la clé n'est pas dans le dict.{'a': None}.get('a', 'I do not want None')
vous donnera toujoursNone
comme résultat.En plus de la réponse de Juliano sur le comportement de "ou": c'est "rapide"
Parfois, cela peut être un raccourci utile pour des choses comme
la source
En plus de la réponse @Bothwells (que je préfère) pour les valeurs uniques, afin de vérifier la valeur nulle des valeurs de retour de fonction, vous pouvez utiliser un nouvel opérateur morse (depuis python3.8):
Ainsi, la
test
fonction n'a pas besoin d'être évaluée deux fois (comme dansa = 2 if test() is None else test()
)la source
Dans le cas où vous devez imbriquer plusieurs opérations de coalescence nulle telles que:
model?.data()?.first()
Ce n'est pas un problème facile à résoudre
or
. Il ne peut pas non plus être résolu avec.get()
lequel nécessite un type de dictionnaire ou similaire (et ne peut pas être imbriqué de toute façon) ougetattr()
qui lèvera une exception lorsque NoneType n'a pas l'attribut.Le pip pertinent envisageant d'ajouter une coalescence nulle au langage est PEP 505 et la discussion pertinente au document se trouve dans le fil d' idées python .
la source
Concernant les réponses de @Hugh Bothwell, @mortehu et @glglgl.
Configuration du jeu de données pour les tests
Définir les implémentations
Faire la fonction de test
Résultats sur Mac i7 @ 2.7Ghz en utilisant Python 2.7
De toute évidence,
not_none
fonction répond correctement à la question de l'OP et gère le problème de "falsification". Il est également le plus rapide et le plus facile à lire. Si vous appliquez la logique à de nombreux endroits, c'est clairement la meilleure façon de procéder.Si vous avez un problème où vous voulez trouver la 1ère valeur non nulle dans un itérable, alors la réponse de @ mortehu est la voie à suivre. Mais c'est une solution à un problème différent de celui de l'OP, bien qu'il puisse gérer partiellement ce cas. Il ne peut pas prendre une valeur itérable ET une valeur par défaut. Le dernier argument serait la valeur par défaut retournée, mais vous ne seriez pas en train de passer un itérable dans ce cas aussi bien qu'il n'est pas explicite que le dernier argument est une valeur par défaut.
Vous pouvez ensuite le faire ci-dessous, mais je l'utiliserais toujours
not_null
pour le cas d'utilisation à valeur unique.la source
Pour ceux comme moi qui ont trébuché ici à la recherche d'une solution viable à ce problème, lorsque la variable peut être indéfinie, le plus proche que j'ai obtenu est:
Notez qu'une chaîne est nécessaire lors de l'archivage des globaux, mais ensuite la variable réelle est utilisée lors de la vérification de la valeur.
En savoir plus sur l'existence de variables: comment vérifier si une variable existe?
la source
(variablename or False) == True
est le même quevariablename == True
si vous ne trouvez pas le nom dans le dictionnaire, il renverra la valeur par défaut, si le nom existe, il ajoutera toute valeur existante avec 1.
j'espère que cela peut aider
la source
Les deux fonctions ci-dessous se sont révélées très utiles pour traiter de nombreux cas de test de variables.
la source