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

Python Discussion :

Déclaration de liste [Python 3.X]


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2016
    Messages : 129
    Points : 40
    Points
    40
    Par défaut Déclaration de liste
    Bonjour,
    quand je déclare une liste "unidimensionnelle" (a=[0]*10), tout se passe bien.

    Par contre quand je passe à une liste 'bidimensionnelle', je ne comprends plus ce qui se passe :

    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
    >>> a=[0]*10
    >>> a
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>> b=[[0]*10]
    >>> b
    [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
    >>> c=[0,10]*10
    >>> c
    [0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10]
    >>> d=[[0,10]]*10
    >>> d
    [[0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10]]
    
    >>> d[2][0]=222
    >>> d
    [[222, 10], [222, 10], [222, 10], [222, 10], [222, 10], [222, 10], [222, 10], [222, 10], [222, 10], [222, 10]]
    >>> e=[]
    >>> for i in range (10):
    ...     e.append([0, 10])
    ... 
    >>> e
    [[0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10]]
    >>> e[2][0]=222
    >>> e
    [[0, 10], [0, 10], [222, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10], [0, 10]]
    >>>
    Considérons d, si je tape 'd[2][0]=222', tous les d[][0] vont avoir la valeur '222', et non seulement d[2][0]=222.

    Par contre, pour 'e', tout se passe correctement.

    Comment déclarer une telle structure de façon aussi concise que possible pour avoir le résultat attendu ?
    Et quelle est la logique derrière un tel comportement ?

    Merci pour votre aide.

  2. #2
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 877
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 877
    Points : 3 721
    Points
    3 721
    Par défaut
    Salut,

    Dans la liste d tu as 10 fois la même liste (10 références à la même liste) alors que dans la liste e tu as 10 listes différentes indépendantes les unes des autres (chaque liste a sa référence).

    Un code à tester pour comprendre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a = [3]
    b = a
    print(a, b) # [3] [3]
    b[0] = 7
    print(a, b) # [7] [7]
    On voit que le changement de la liste b se répercute à la liste a et ce parce que a et b pointent sur la même liste.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par jam7575 Voir le message
    Comment déclarer une telle structure de façon aussi concise que possible pour avoir le résultat attendu ?
    Et quelle est la logique derrière un tel comportement ?
    Si j'écris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> A = []
    >>> B = [A, A, A]
    et que je modifie A:
    je me retrouve avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> B
    [[1], [1], [1]]
    >>>
    Et il est "logique" de dire que si B contient 3 fois le même objet, si je modifie l'objet, la modification apparaît 3 fois. Et si je ne veux pas çà, je construis B avec 3 objets différents:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> B
    [[], [], [1]]
    >>> A.append('x')
    >>> B
    [[], [], [1, 'x']]
    >>>
    Là ou vous vous faites avoir c'est avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>> a[1] = 123
    >>> a
    [0, 123, 0, 0, 0, 0, 0, 0, 0, 0]
    >>>
    Comme un nombre n'est pas mutable/modifiable, pour changer a[1] il faut lui assigner un autre objet (et non modifier l'objet existant).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre du Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2016
    Messages : 129
    Points : 40
    Points
    40
    Par défaut
    merci beaucoup,
    mais pourquoi le même déroulement ne vaut pas pour "a" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> a[2]=3
    >>> a
    [0, 0, 3, 0, 0, 0, 0, 0, 0, 0]
    >>>
    Cordialement.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par jam7575 Voir le message
    mais pourquoi le même déroulement ne vaut pas pour "a" ?
    a[2] = 3 assigne l'objet 3 à la position 2 de la liste.
    On ne modifie pas l'objet en position 2 mais on en met un autre à la place.

    Plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >> A = []
    >>> B = A
    >>> A.append(1)
    >>> B
    [1]
    >>>
    A et B sont associé à la même liste. Si je modifie la liste en y accédant par A, l'objet accédé via B montrera la modification (c'est le même).
    Si j'écris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> A = 1
    >>> B = A
    >>> A = 2
    >>> B
    1
    >>>
    Ici 1 est un entier impossible à modifier (pas mutable). Si on assigne un autre entier à A, B n'a aucune raison d'être mis à jour (assigner un autre objet <=> ce ne sont plus les mêmes).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 699
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 699
    Points : 30 999
    Points
    30 999
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par jam7575 Voir le message
    Et quelle est la logique derrière un tel comportement ?
    Python travaille à l'économie. Il en fait le minimum pour correspondre à la demande initiale. Tu as demandé dix couples (0, 10) il en a créé un seul (plus rapide que d'en créer dix différents) dont il a récupéré et stocké dix fois la référence. Au final tu obtiens bien dix couples (0, 10). Que ces dix couples soient en réalité dix références au même n'est pas en contradiction avec ta demande initiale. Tu aurais voulu dix couples différents il fallait le préciser.

    Citation Envoyé par jam7575 Voir le message
    Comment déclarer une telle structure de façon aussi concise que possible pour avoir le résultat attendu ?
    d=[[0, 10] for i in range(10)].

    Citation Envoyé par jam7575 Voir le message
    mais pourquoi le même déroulement ne vaut pas pour "a" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> a[2]=3
    >>> a
    [0, 0, 3, 0, 0, 0, 0, 0, 0, 0]
    >>>
    Ecrire a[2]=3 n'est pas une modification du contenu actuel de a[2] mais une nouvelle affectation par autre chose. Tu aurais pu, dans ton premier exemple, écrire aussi d[2]=3 cela aurait aussi fonctionné. Mais d[2][0]=3 là c'est une modification de l'objet contenu dans d[2]. Et comme cet objet est aussi dans d[0] et dans d[1] et ... jusqu'à d[9]...

    Autre exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a=500
    >>> b=a
    >>> id(a)
    140366632449520
    >>> id(b)
    140366632449520
    La copie de "b" dans "a" se fait via leurs identifiants. Au final "a" et "b" référencent le même objet "int(500)".

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> b=500
    >>> id(a)
    140366632449520
    >>> id(b)
    140366632449488
    Mais ensuite modifier "b", même en lui mettant la même valeur, lui affecte là un autre objet "int(500)".
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre du Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2016
    Messages : 129
    Points : 40
    Points
    40
    Par défaut
    Merci,
    c'est très clair,
    mais alambiqué.
    Je crois que c'est la seconde fois que je me fais avoir avec cette 'particularité' de Python. Les années passent...
    Cordialement

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. liste déclaration de prédicat
    Par tanguy.L dans le forum Prolog
    Réponses: 1
    Dernier message: 14/03/2010, 23h57
  2. déclaration d'une liste circulaire
    Par infonew dans le forum C
    Réponses: 1
    Dernier message: 26/03/2008, 22h20
  3. Déclaration d'un type Liste
    Par pépé35 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 06/10/2007, 23h22
  4. Erreur sur déclaration de liste
    Par La Truffe dans le forum C++
    Réponses: 4
    Dernier message: 19/02/2006, 19h38
  5. Réponses: 16
    Dernier message: 19/11/2005, 16h47

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