• [^] # Re: Python se rapproche du Perl ?

    Posté par (site web personnel) . En réponse à la dépêche Python 3.8 : opérateur d’assignation, REPL async, Pickle v5 et plus. Évalué à 10.

    Avec plaisir. Alors, l'explication de texte:

    def f(a, /, d, *, e):
     l: Dict[int,int] = { 5:9, **{ v: v**2 for v in d if (t:=v%2) } }
     return l
    

    Pour ce qui des arguments de la fonction f: / comme epxliqué dans la dépêche implique que a peut être passé uniquement en paramètre positionnel, d peut être passé un paramètre positionnel ou par mot-clé et e ne peut peut être passé que par mot-clé.

    Concrètement:

    >>> f({},{},{})
    Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
    TypeError: f() takes 2 positional arguments but 3 were given
    >>> f({},{},e={}) # ca marche
    {5: 9}
    >>> f({},d={},e={}) # ca marche aussi
    {5: 9}
    >>> f(a={},d={},e={}) # et non, a ne peut pas être passé par mot-clé
    Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
    TypeError: f() got some positional-only arguments passed as keyword arguments: 'a'
    

    La partie l: Dict[int,int], c'est juste pour le sport. Ça déclare une variable annotée en tant que dictionnaire avec des clés de type entier et des valeurs de type entier. Pour rappel, les annotations sont ignorées par Python, il faut lancer un outil externe comme mypy pour en tirer quelque chose.

    La nouvelle syntaxe permettant du unpacking dans les dictionnaires: {5:9, **dict}, cela crée un nouveau dictionnaire, avec d'une part une clé 5 associée à la valeur 9, et toutes les autres clés-valeurs sont piochées dans le dictionnaire qui suit le **.

    Les dict comprehensions {v: v**2 for v in d }, cela crée un dictionnaire dont les clés seront v et associées aux valeur v**2 c'est à dire v puissance 2. La valeur v est piochée en parcourant les clés du dictionnaire d.

    On rajoute ensuite un filtre sur les valeurs qu'on pioche dans d via if v%2, en ne gardant que celles qui vérifient v%2 est vrai, c'est à dire v%2 différent de zéro, c'est à dire les nombres impairs. On a donc l'explication du { v: v**2 for v in d if v%2 }.

    Le (t:=v%2) permet de stocker la valeur v%2 dans une variable t, c'est la nouveauté du Python 3.8 expliquée dans la dépêche.

    En pratique:

    >>> t # variable does not exist yet
    Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
    NameError: name 't' is not defined
    >>> d={1:2, 2:3, 4:5}
    >>> l: Dict[int,int] = { 5:9, **{ v: v**2 for v in d if (t:=v%2) } }
    >>> t
    0
    >>> l
    {5: 9, 1: 1}