IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

affecter valeurs tableau


Sujet :

Calcul scientifique Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 67
    Par défaut affecter valeurs tableau
    Bonjour,

    Pour mettre des valeurs dans un tableau avec python, je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    gh = 0
    t = []
    for i in xrange(15):
          t[i] = gh
          gh = gh + 1
    mais cela affiche une erreur, est-ce qu'il faut faut nécessairement utiliser le append ?
    Sans utiliser append, comment faudrait-il l'écrire ?

    Pour xrange, si on écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for i in xrange(2, 16, 0.01)
    pourquoi ne peut-il pas avancer par pas de 0.01 ?


    Merci de votre aide.

  2. #2
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Comment utiliser l'index avec une liste dont l'index est à zéro ? Comme ceci peut etre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> t = range(15)
    >>> type(t)
    <type 'list'>
    >>> print t
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    >>> t = list(xrange(15))
    >>> print type(t)
    <type 'list'>
    >>> print t
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

    Sinon pour xrange :
    step must not be zero (or else ValueError is raised)
    .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> a = 0.1
    >>> print int(a)
    0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def Xrange(start=0, stop=0, step=1):
        if step < 0:
            while start > stop:
                yield start
                start = start + step
        else:
            while start < stop:
                yield start
                start = start + step
     
    for elems in Xrange(1.0, 10.0, 0.1):
        print(elems)
    @+

    Edit: Par contre list(Xrange(15)) ne fonctionne pas très bien. Cela viens sans doute de mon code...

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bon,

    Après test les solutions les plus stables pour xrange et 0.1 sembles etre une fonction dans le style Xrange pour ce qui d'une utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for elems in Xrange(0.0, 15.0, 0.1):
        print(elems)
    Mais cela n'est pas utilisable pour créer directement une liste avec list.
    Pour générer une liste numpy s'en sort très bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import numpy as np
    t = np.arange(0, 15, 0.1)
    Mais je suis étonné des résultats de mes différents tests (cela viens de list ?)... Je vais y regarder de plus pres.

    @+

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Citation Envoyé par space_56 Voir le message
    Sans utiliser append, comment faudrait-il l'écrire ?
    On peut initialiser le tableau avec range ou comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    gh = 0
    t = [0 for i in xrange(15)]
    for i in xrange(15):
          t[i] = gh
          gh = gh + 1
    print t
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    Citation Envoyé par space_56 Voir le message
    pourquoi ne peut-il pas avancer par pas de 0.01 ?
    Parce que xrange ne supporte que les entiers. Et seulement le type int et pas le type long.

    Voilà un code qui simule le comportement de xrange pour les flottants et les long:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    def xplage(*arg):
        lga = len(arg)
        if lga == 1:
            xmin, xmax, xpas = 0, arg[0], 1
        elif lga == 2:
            xmin, xmax, xpas = arg[0], arg[1], 1
        elif lga == 3:
            xmin, xmax, xpas = arg[0], arg[1], arg[2]
        else:
            raise ValueError ("Erreur xplage: nombre d'arguments doit être 1,2,ou 3")
        if xpas == 0:
            raise ValueError ("Erreur xplage: le pas ne peut être nul")
        x = xmin
        if isinstance(xpas, float):
            eps = xpas/10.0
        else:
            eps = 0
        if xpas>0:
            if xmax<xmin:
                raise ValueError ("Erreur xplage: bouclage infini")
            while x+eps<xmax:
                yield x
                x += xpas
        else:
            if xmax>xmin:
                raise ValueError ("Erreur xplage: bouclage infini")
            while x+eps>xmax:
                yield x
                x += xpas
    Avec ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for i in xplage(2, 16, 0.01):
        print i
    2
    2.01
    2.02
    2.03
    ...
    15.97
    15.98
    15.99
    NB: conformément au xrange, on n'a jamais la dernière valeur.

    Ce code fonctionne aussi pour:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    xplage(2)
    xplage(2, 16)
    xplage(2, -16, -0.01)
    xplage(9999999999999999999999999999999999999999L, 9999999999999999999999999999999999999999L+10L):
    Et détecte les données anormales => exception.

    Tyrtamos

  5. #5
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour tyrtamos,

    Je me retrouve avec dans ton code dans le même cas de figure que dans mes essais, soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    t1 = []
    for i in xplage(2, 3, 0.1):
        print i
        t1.append(i)
    t = list(xplage(2, 3, 0.1))
    print t
    print t1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    2
    2.1
    2.2
    2.3
    2.4
    2.5
    2.6
    2.7
    2.8
    2.9
    [2, 2.1000000000000001, 2.2000000000000002, 2.3000000000000003, 2.40000000000000
    04, 2.5000000000000004, 2.6000000000000005, 2.7000000000000006, 2.80000000000000
    07, 2.9000000000000008]
    [2, 2.1000000000000001, 2.2000000000000002, 2.3000000000000003, 2.40000000000000
    04, 2.5000000000000004, 2.6000000000000005, 2.7000000000000006, 2.80000000000000
    07, 2.9000000000000008]
    Dès que j'utilise les données (map etc) je me retrouve avec un résultat 'différent' Aurais tu une explication ? J'ai bien vu des avertissements sur la virgule, hors modules spécifiques, à droite et gauche mais je n'arrive pas à comprendre.
    Le seul qui me donne le bon résultat c'est arange de numpy mais pour lire les sources... (chez moi c'est un .so)...

    @+

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour PauseKawa,

    Il s'agit seulement d'un problème d'affichage bien connu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    print 2.3000000000000003, [2.3000000000000003]
    2.3 [2.3000000000000003]
    En effet, les vrais résultats de la boucle sont les suivants (on utilise repr() pour avoir tous les chiffres):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    t1 = []
    for i in xplage(2, 3, 0.1):
        print repr(i)
        t1.append(i)
    2
    2.1
    2.2
    2.3000000000000003
    2.4000000000000004
    2.5000000000000004
    2.6000000000000005
    2.7000000000000006
    2.8000000000000007
    2.900000000000001
    Et l'intégration des ces valeurs à l'intérieur d'une liste ne les change pas, mais les affiche complètement.

    Pour échapper à cela, qui ne concerne que l'affichage, il faut utiliser un code d'affichage qui transforme la liste en chaine, et qui force l'utilisation de str au lieu de repr. Comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    def formatliste(L):
        """création d'une chaine à partir d'une liste de nombres pour affichage """
        ch = '['
        if len(L)>0:
            for x in L:
                ch += "%s, " % x
            ch = ch[:-2] # on retire la dernière virgule en trop
        ch += ']'
        return ch
     
    print formatliste(t1)
    [2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9]
    Bien sûr, pour afficher un arbre de profondeur quelconque (liste de listes de listes...) avec des données quelconques, des instructions d'affichage des flottants et des problèmes d'encodage des chaines, c'est un peu plus compliqué. Un exemple sur mon site: http://python.jpvweb.com/mesrecettes....php?id=printx

    Tyrtamos

  7. #7
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Désolé tyrtamos, j'ai du mal...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    t1 = []
    for item in xplage(1, 2, 0.5):
        t1.append(item)
    t2 = []
    for item in xplage(1, 2, 0.1):
        t2.append(item)
    print(t1[1])
    print(t2[5])
    print(t1[1] == t2[5])
    C'est moi ou c'est plus qu'un problème d'affichage ?
    Un lien vers une explication sur le sujet (j'ai bien vu des warning sur le sujet mais ma logique ne suit pas...) ?

    Merci d'avance

  8. #8
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Il faut distinguer le fait que 'print x' arrange l'affichage de x en 'oubliant' les tous derniers chiffres derrière la virgule et en arrondissant en conséquence. Ce qui nous convient la plupart du temps. Mais ça ne change pas le vrai nombre en mémoire qui comporte tous ses chiffres.

    Dans ton dernier exemple:

    print(t1[1]) affiche 1.5, et c'est bien 1.5 (print repr(t1[1])) affiche 1.5)

    mais:
    print(t2[5]) affiche 1.5, mais c'est en réalité 1.5000000000000004 (c'est ce que donne print repr(t2[5])))

    Ce qui fait que 1.5==1.5000000000000004 donne False, et c'est très bien ainsi.

    Autre essai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    print str(1.5000000000000004)
    1.5
    print repr(1.5000000000000004)
    1.5000000000000004
    Ok?

    Tyrtamos

  9. #9
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    J'avais bien compris mais pour moi 1 + 0.5 == 1 + (0.1 * 5) et 1 + (0.1 * 5) != 1.5000000000000004. Pour moi c'est une erreur de calcul (d'où viens le 4 ?) et non d'affichage.
    Mais je ne vais pas polluer plus le sujet de space_56. Je vais regarder cela et je reviendrais avec un autre sujet si besoin.

    Merci

  10. #10
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Tu n'as pas tort sur un point: en plus des pb d'affichage, il y a effectivement des pb de calcul pour la raison suivante: les nombres sont stockés sous forme binaire, et il est impossible de représenter exactement 0.1 (par exemple) sous forme binaire: il y a donc une erreur dû, non au calcul lui-même, mais au stockage du nombre en mémoire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    x = 1
    while x<2:
          print repr(x)
          x += 0.1
    1
    1.1
    1.2000000000000002
    1.3000000000000003
    1.4000000000000004
    1.5000000000000004
    1.6000000000000005
    1.7000000000000006
    1.8000000000000007
    1.9000000000000008
    Python ne fait qu'utiliser la bibliothèque du C qui fait donc la même chose.

    Pour échapper complètement à ça, il faut choisir un autre mode de stockage en mémoire comme le module décimal en Python. En contrepartie, c'est moins rapide.

    Tyrtamos

  11. #11
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Je viens de relire 14.1. Representation Error et c'est enfin rentrer... (il était temps).
    Du coup j'ai honte alors pour me rattraper : t = [0 for _ in xrange(15)]

    @+

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Désolé mais ce n'est pas qu'un problème d'affichage, dans la suite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    1.1
    1.2000000000000002
    1.3000000000000003
    1.4000000000000004
    1.5000000000000004
    1.6000000000000005
    1.7000000000000006
    1.8000000000000007
    1.9000000000000008
    "On voit" qu'une déviation s'accumule à chaque itération.
    Techniquement, pour éviter cela, il est raisonnable de faire qqc. comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def frange(min, max, step):
        for c in range (int((max - min) / step)):
            yield min + c * step
    i.e. les imprécisions se compensent à chaque étape.

    Bien sûr il y aura toujours de l'imprécision (à traiter), mais moins d'erreurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    1.0
    1.1
    1.2
    1.3
    1.4
    1.5
    1.6
    1.7000000000000002
    1.8
    1.9
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonsoir wiztricks,

    C'est bien ce que dit tyrtamos et la doc.
    D'où, sans doute, le fait que les résultats d'un arange (ce n'est pas du Python) de numpy donne des résultats plus justes (d'après mes 'petits' tests).
    En résumé il est préférable d'utiliser les modules de calcul pour les float.

    @+

  14. #14
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Salut PauseKawa,

    La doc dit qu'on ne sait pas faire une bijection entre les représentations base 10 et binaires mais cela nous le savions.
    Mon propos est d'essayer d'expliquer pourquoi arange travaille mieux car in fine, dans les deux cas, nous avons la même bibliothèque C, même CPU
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Et je t'en remercie wiztricks.
    Tout ce que je voulais dire c'est que la déviation en question prend du temps de calcul pour la correction, d'où un avantage à utiliser arange (optimisé) plutôt que de revoir le monde.

Discussions similaires

  1. affectation valeur dans une cellule d'un tableau
    Par Sasuke1234 dans le forum MATLAB
    Réponses: 1
    Dernier message: 13/02/2014, 08h48
  2. [Twig] Affectation valeur tableau
    Par chlock62 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 11/12/2013, 11h31
  3. affectation valeur tableau
    Par gourmand dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 30/05/2011, 13h23
  4. affectation valeur a un tableau
    Par ludovic85 dans le forum Linux
    Réponses: 2
    Dernier message: 13/12/2006, 12h54
  5. problème d'affectation de tableau ...
    Par Mike888 dans le forum C
    Réponses: 23
    Dernier message: 26/02/2005, 14h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo