Forum Programmation.python tableau d'entiers

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
16
juin
2020

Coucou les pros du pyhton qui passeraient dans le coin.

J'ai un tableau d'unsigned chars (ie: toto = array.array('B', [5, 8, 9, 15])), préalablement ordonné (la première valeur est toujours la plus petite).

J'aimerais en sortie que toutes les valeurs du tableau soient minorées de la première. Dans l'exemple, le tableau toto contiendrait donc 0, 3, 4, 10.

Je peux facilement le faire avec un for et un tableau intermédiaire (ou directement dans le tableau d'origine, j'ai pas creusé la question), mais je me demande s'il y a un moyen plus pythoniquement correct de résoudre le problème. Du style un one liner obscur plus optimal.

Pour ma culture générale :)

Merci d'avance.

  • # Méthode de base

    Posté par  . Évalué à 3.

    Salut,

    C'est peut-être adaptable. Là, c'est sur un tableau, pas un objet array :

    >>> a=[5, 8, 9, 15]
    >>> b=[x -a[0] for x in a]
    >>> b
    [0, 3, 4, 10]

    Mais j'ai peut-être pas compris…

    Matricule 23415

    • [^] # Re: Méthode de base

      Posté par  . Évalué à 1.

      Oui c'est ça.
      En fait je crois que ce que tu me propose c'est une liste, plutot qu'un tableau (mais c'est pas exclu que je ne sache pas ce que je dis).
      J'ai préfère un objet array parce que c'est typé, et que ça m'arrange de pas tester chaque cas pour voir si j'ai le droit de faire une soustraction. C'est peut-être superflu parce que l'utilisateur n'a pas la main sur ces données là mais bon, ça me semblait plus "propre".

      • [^] # Re: Méthode de base

        Posté par  . Évalué à 2.

        En python, le type array (enfin vecteur pour moi) n'existe pas en tant que tel. Il faut utiliser des listes et elles sont non typées. D'une manière générale, python est un langage non typé, même si tu peux préciser les types attendu dans tes fonctions depuis pytho 3.7 il me semble.

        Si tu veux quelque chose de plus efficace et typé, utilise la bibliothèque numpy.

        • [^] # Re: Méthode de base

          Posté par  (site web personnel) . Évalué à 4.

          Quelque chose comme :

          >>> import numpy as np
          >>> a = np.asarray([7, 3,4,5,6]);a
          array([7, 3, 4, 5, 6])
          >>> a=a-a[0];a
          array([ 0, -4, -3, -2, -1])

          ?

          « IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace

        • [^] # Re: Méthode de base

          Posté par  . Évalué à 1. Dernière modification le 17 juin 2020 à 12:08.

          Ben il y a array qui est standard et fais ce que je lui demande. Numpy à l'air très bien, mais ça me semble un peu overkill, je travaille juste sur des entiers non signés, j'ai pas vraiment besoin d'une lib orientée calcul scientifique, et qui va me faire une dépendance supplémentaire.

          Après, tous les conseils sont bon à prendre.

          • [^] # Re: Méthode de base

            Posté par  . Évalué à 2.

            Salut,

            Réponse en deux temps ;)

            1. Alors oui, tu as raison il me semble, c'est une liste dans ce que j'ai posté.

            2. Après, mais là, c'est à toi de voir (je n'ai pas regardé le code source de l'objet array) mais j'opterais pour un objet qui l'étende avec une fonction en plus qui fais ce que tu veux. Ça sera plus clair et maintenable s'il y a plusieurs endroits où la manipulation doit être faite. Mais là, c'est juste mon avis perso, tu n'es pas obligé de le suivre :)

            Matricule 23415

        • [^] # Re: Méthode de base

          Posté par  (site web personnel) . Évalué à 1.

          Il faut utiliser des listes et elles sont non typées. D'une manière générale, python est un langage non typé

          Python est un langage typé dynamiquement. Chaque élément en mémoire à un type (que ce soit une variable, une fonction, une classe, un module, etc.).

          >>> type(12)
          <class 'int'>
          >>> import os
          >>> type(os)
          <class 'module'>

          Par exemple, il n'est pas possible de concaténer une chaîne de caractère et un entier :

          >>> "a" + 1
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          TypeError: can only concatenate str (not "int") to str

          Cependant, contrairement à un typage statique (comme en C, Java, etc.), la vérification du typage est fait à l'exécution, ce qui donne l'impression qu'il n'y a pas de typage. En pratique, ceux qui préfèrent un typage statique pour sa capacité de vérification des types lors de la compilation assimilent le comportement de Python à un langage non typé car il ne permet pas cela. Cependant, le typage de Python permet de détecter certaines erreurs (à l'exécution) lorsque certains problèmes de type surviennent plutôt que dans une exécution plus lointaine du programme comme le ferait un langage non typé.

          tu peux préciser les types attendu dans tes fonctions depuis pytho 3.7

          Oui, l'apparition du type hinting permet d'indiquer le type attendu en paramètre et en sortie des fonctions et méthodes. Cela permet de vérifier statiquement dans certains cas les appels. Cela dit, ça reste limité et ne sera probablement jamais aussi implacable qu'un typage statique.

          >>> def plus_un(entier: int) -> int:
          ...  return entier + 1
  • # Pas trop le choix…

    Posté par  (site web personnel) . Évalué à 4.

    Tu serais avec un tableau numpy, tu pourrais faire une opération globale. Là avec un tableau array.array() tu n'as pas trop le choix que de parcourir les éléments un à un, avec une boucle explicite ou une liste en compréhension (exemple ci-dessus) ou une expression génératrice (comme ci-dessous).

    >>> import array
    >>> toto = array.array('B', [5, 8, 9, 15])
    >>> toto2 = array.array('B', (x-toto[0] for x in toto))
    >>> toto2
    array('B', [0, 3, 4, 10])

    Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

    • [^] # Re: Pas trop le choix…

      Posté par  . Évalué à 2.

      Salut,

      Merci pour ton complément (et comme en plus je sais que t'es achtement plus balaise en python que moi… ;) ).

      Je vais chercher encore un peu, je crois que je ne suis pas loin.

      Je demande quand même au cas où tu as 30 secondes (et ça peut peut-être aider l'OP).

      Si je comprends bien ton exemple, les parenthèses sont là pour définir la fonction génératrice (pas de problème).

      En fait, la question est la suivante : fonction génératrice == lambda ? Ou pas du tout ?

      Merci, si tu as le temps.

      Matricule 23415

      • [^] # Re: Pas trop le choix…

        Posté par  . Évalué à 2.

        Re salut,

        Ah, non, ça a pas l'air pareil :)

        J'ai surtout des réponses en stats (étrange… serais-je surveillé ?). Mais bon, je vois un peu mieux.

        Matricule 23415

        • [^] # Re: Pas trop le choix…

          Posté par  . Évalué à 2.

          Re re salut,

          Bon, ok, je pense avoir compris la différence :)

          Ça se rapproche plus d'un itérateur.

          Mais au cas où, si jamais…

          Matricule 23415

          • [^] # Re: Pas trop le choix…

            Posté par  (site web personnel) . Évalué à 2.

            (passages à l'occasion sur le forum)

            Le générateur est un itérateur qui produit les données au fur et à mesure des besoins, l'expression (expr for truc in machin) est une expression génératrice — comme une liste en compréhension mais avec des parenthèses et pas des crochets. Si tu as une grande quantité de données ça évite de faire une grande copie en mémoire (ce que fait une liste en compréhension).

            Après, je ne sais pas comment array() se construit à partir de l'itérable qu'on lui fournit en paramètre (s'il fait une pré-allocation, il va chercher à connaître le nombre d'éléments, et dans ce cas je ne sais pas comment ça fait avec le générateur, faudrait voir la cuisine interne).

            Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

    • [^] # Re: Pas trop le choix…

      Posté par  . Évalué à 1.

      Je vais faire ça, merci pour vos réponses à tous :D

  • # map() ?

    Posté par  (Mastodon) . Évalué à 2. Dernière modification le 17 juin 2020 à 07:58.

    Débutant en python, je tente toute de même une approche : map() ?

    Un exemple sorti du premier résultat de google :

    # Add two lists using map and lambda 
    
    numbers1 = [1, 2, 3] 
    numbers2 = [4, 5, 6] 
    
    result = map(lambda x, y: x + y, numbers1, numbers2) 
    print(list(result))

    Affichage :

    [5, 7, 9]

    En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

    • [^] # Re: map() ?

      Posté par  . Évalué à 1.

      J'ai tendance à utiliser zip dans une situation comme ça:

      numbers1 = [1, 2, 3]
      numbers2 = [4, 5, 6]
      
      result = [x + y for x, y in zip(numbers1, numbers2)] 
      print(result)

      Ce qui donne le même résultat

    • [^] # Re: map() ?

      Posté par  . Évalué à 1.

      C'est pas exactement ce que je cherche à faire, mais je garde ça sous le coude :D

      • [^] # Re: map() ?

        Posté par  (Mastodon) . Évalué à 4.

        bin si il me semble

        numbers = [4, 5, 6] 
        
        min=numbers[0]
        result = map(lambda x: x - min, numbers) 
        print(list(result))

        Donne :

        [0, 1, 2]

        Non ?

        En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.