Python intéressant et utile

Je programme en python depuis plusieurs années, cependant, j'ai récemment réalisé que beaucoup de trucs utiles et de moments intéressants m'ont passé, peut-être que je ne suis pas le seul, alors j'ai décidé de les énumérer ici, j'espère que ces trucs seront utiles à quelqu'un au travail ou me feront faire connaissance avec cette langue plus proche.

Comme dans de nombreux langages en python, 1 est équivalent à True et 0 est False, c'est-à-dire

1 == True. 

Il semblerait, et qu'est-ce qui ne va pas avec ça? Cependant, cela a certains effets secondaires associés au fait que les mêmes objets doivent avoir les mêmes hachages, vous ne pourrez donc pas entasser la clé 1 et True dans un même dictionnaire.

  >>> a = {1: "one", 0: "zero", True: "true", False: "false"} # -> {1: 'true', 0: 'false'} 

Il permet également les opérations suivantes:

  >>> print(2 * False + True) # -> 1 

Dans cet exemple, les chaînes ont été utilisées comme valeurs de dictionnaire, cependant, je veux souvent les utiliser comme clés de dictionnaire, j'ai toujours été ennuyé que lors de la création d'un dictionnaire avec des accolades, vous devez spécifier les chaînes entre guillemets, je voudrais les omettre, c'est possible si vous créez dictionnaire via le constructeur dict ().

  >>> {"one": 1, "two": 2, "three": 3} == dict(one=1, two=2, three=3) # -> True 

De plus, non seulement les dictionnaires, mais aussi les ensembles (ensemble) sont créés à l'aide d'accolades.

  >>> a = {1, 2, 3} 

Pour combiner les deux ensembles, pour une raison quelconque, je veux utiliser l'opérateur +, probablement en raison de la façon dont les chaînes sont concaténées. Cependant, python ne prend pas en charge cet opérateur pour les ensembles. Mais bien sûr, cela ne signifie pas que nous devons toujours utiliser des fonctions, les créateurs ont abordé ce problème plus systématiquement et ont ajouté la prise en charge des opérations de base sur les ensembles (pas seulement les unions) au langage et les ont "accrochés" aux opérateurs logiques .

 a = {1, 2, 3} b = {0, 2, 4} print(a & b) # -> {2} print(a | b) # -> {0, 1, 2, 3, 4} print(a ^ b) # -> {0, 1, 3, 4} print(a - b) # -> {1, 3},    #     

Poursuivant la conversation sur les dictionnaires, à partir de la version 3.7, la spécification de langue garantit que les dictionnaires préservent l'ordre d'insertion des éléments, OrderedDict n'est plus nécessaire.

www.python.org/downloads/release/python-370
mail.python.org/pipermail/python-dev/2017-December/151283.html

 d = dict(zero='Cero', one='Uno', two='Dos', three='Tres', four='Cuatro', five='Cinco', six='Seis', seven='Siete', eight='Ocho', night='Nueve') for index, (key, value) in enumerate(d.items()): print(f"{index} is {key} in England and {value} in Spain") 

Faites attention à la ligne de sortie, elle commence par le préfixe f - c'est un type spécial de lignes introduit en python 3.6 .

Il existe trois types de chaînes dans la langue: régulière, indiquée par des guillemets sans préfixe, brute \ non traitée (brute), dans laquelle les caractères spéciaux, comme \ n, ne sont pas traités et insérés sous forme de texte et de lignes f elles-mêmes.

Ils ont été créés pour simplifier la sortie, python prend en charge un grand nombre de méthodes de sortie:

 print("result" + str(2)) #   , python   #      #  ,     print("result", 2) # print      , #        , #        , #      print("result %d" % 2) # %-,      C. print("result %d %.2f" % (2, 2)) # https://docs.python.org/3.4/library/string.html#formatspec print("result %(name)s" % {"name": 2}) #      print("{}".format(2)) #      format() #       print("{0} {1} {0}".format(1, 2)) #          #     #     #        ,    print("{} {}".format(2)) # -> IndexError: tuple index out of range print("{0} {0}".format(2, 3)) # -> 2 2       #     from math import pi #         print("{:.2f}".format(pi)) # -> 3.14 from string import Template #      s = Template("result $res") #       print(s.substitute(res = [3, 4])) 

Maintenant ajouté plus de lignes f. Toutes les variables de la portée y sont disponibles, vous pouvez appeler des fonctions, obtenir des éléments par clé, en plus, elles prennent en charge les chaînes de format.

 from math import pi result = 4 name = "user" print(f"{name:84s} pi= {pi:.2f}, result={result}, {name[2]}") # -> user pi= 3.14, result=4, e from datetime import datetime print(f"{datetime.now():%Y:%m-%d}") 

Ils sont plus rapides que toutes les autres méthodes de sortie, donc si python3.6 est disponible, il est recommandé de les utiliser.

L'un des morceaux de python les plus cool - non pas les objets et les primitives y sont emballés et décompressés, mais les paramètres et les collections.

 def func(*argv, **kwargs) 

Cependant, il existe un défaut architectural dans la mise en œuvre:

  • argv - un tuple, ses valeurs ne peuvent pas être modifiées, les valeurs ne peuvent pas être ajoutées ou supprimées
  • kwargs est un dictionnaire mutable, donc la mise en cache n'est pas possible

L'inconvénient, bien sûr, n'est pas important, mais il est toujours désagréable que vous ne puissiez pas transférer directement les kwargs vers un cache basé sur un dictionnaire, en revanche, si vous ajoutez une liste à un tuple, un tel tuple ne peut pas non plus être ajouté au dictionnaire.

Les ensembles sont également créés sur la base d'une table de hachage, ce qui signifie que les valeurs doivent être hachées.En outre, l'ensemble lui-même est un type mutable et non haché, il existe un type spécial de frozenset - un ensemble immuable (ne me demandez pas pourquoi il est nécessaire).

Ils ont discuté de la création du type frozendict, mais ne l'ont pas encore ajouté (bien qu'il ait déjà au moins une application - comme kwargs). Pour un dictionnaire immuable, namedtuple doit être gonflé. Et aussi pour les notes et les cours sans prétention.

Au cours de ses années scolaires, qui a écrit des cycles pour afficher les valeurs du tableau et qui était furieux à la fin de la virgule, chaque fois qu'il a décidé de marquer ou de réécrire pour être beau, et seulement dans le cours 2-3, a-t-il appris la méthode de jointure? Ou suis-je le seul?

L'une des caractéristiques désagréables de la méthode join pour les chaînes est qu'elle ne fonctionne qu'avec des éléments de chaîne, si la collection a au moins une non chaîne, vous devez utiliser une expression de générateur, ce qui semble une solution trop compliquée à une tâche aussi simple, cependant, il existe un moyen de simplifier la sortie des valeurs de liste (sans crochets) .

 a = list(range(5)) print(" ".join(a)) # -> TypeError: sequence item 0: expected str instance, int found print(" ".join(str(i) for i in a)) # -> 0 1 2 3 4 print(*a) # -> 0 1 2 3 4 

Comme les chaînes sont également des collections, elles peuvent également être «jointes».

 print('-'.join("hello")) # -> hello 

Considérez la ligne de l'exemple précédent.

 print(" ".join(str(i) for i in a)) # -> 0 1 2 3 4 

L'expression du générateur est transmise à la fonction de jointure sans aucun crochet; les parenthèses peuvent être omises pour simplifier la lecture du code. Python prend soin de l'expressivité.

 print(sum(i**2 for i in range(10))) # -> 285 

De plus, les parenthèses peuvent être omises lors de la création de tuples:

 article = "python", 2018, "LinearLeopard" #   theme, year, author = "python", 2018, "LinearLeopard"#   theme, year, _ = "python", 2018, "LinearLeopard" #     #    # ,  , #  -   , #    #  theme, _, _ = "python", 2018, "LinearLeopard" #    theme, *, author = "python", 2018, "LinearLeopard" #    # ,   #  , # ,  #   #   

L'astérisque peut également être utilisé dans les déclarations de fonction, vous pouvez donc créer des paramètres qui ne peuvent être spécifiés que par clé .

 def sortwords(*wordlist, case_sensitive=False): 

Vous pouvez passer autant de paramètres que vous le souhaitez sans craindre que l'un d'entre eux soit perçu comme la valeur du paramètre case_sensitive.

C'est possible et ainsi.

 def func(first, second, *, kwonly): 


Nous allons voir de plus près en quoi il * diffère simplement des * arguments.

 def func(first, second, *, kwonly=True): print(first, second, kwonly) def func2(first, second, *args, kwonly=True): print(first, second, *args, kwonly) func(1) #-> TypeError: func() missing 1 required positional argument: 'second' func(1, 2) #-> 1 2 True func(1, 2, False) #-> TypeError: func() takes 2 positional arguments but 3 were given #  *    ,  #        #   func(1, 2, kwonly=False) #-> 1 2 False func2(1, 2, False) #-> 1 2 False True # *args      # ,       #    (>2)  #  


Une caractéristique intéressante est associée aux paramètres par défaut: ils sont calculés au stade de la compilation du module en bytecode, il est donc préférable de ne pas y utiliser de types mutables. Nous déclarons une fonction qui ajoute un élément à la fin de la liste, si le deuxième argument est omis, la fonction renvoie une nouvelle liste contenant uniquement cet élément.

 def add_to(elem, collection=[]): collection.append(elem) return collection a = ["a", "c"] print(add_to("b", a)) # -> ['a', 'c', 'b'] print(add_to("a")) # -> ['a'] print(add_to("b")) # -> ['a', 'b']   'a'? 

Les valeurs par défaut sont stockées dans le champ __defaults__, vous pouvez savoir ce qui est là à tout moment.

 print(add_to.__defaults__) # -> (['a', 'b'],) 

Étant donné que l'argument par défaut (une liste vide) a été créé au moment où le programme a démarré et n'a pas été recréé à chaque fois, nous avons exactement ce comportement.

Vous pouvez corriger ce comportement si vous définissez la valeur par défaut comme un type immuable et créez une liste dans le corps de la fonction:

 def add_to(elem, collection=None): collection = collection or [] collection.append(elem) return collection 

Faites attention à la commande

 collection = collection or [] 

c'est un analogique plus court (et moins clair, mais pas pour tout le monde)

 collection = collection if collection else [] 


Lien vers la partie suivante

Source: https://habr.com/ru/post/fr421993/


All Articles