Partage
  • Partager sur Facebook
  • Partager sur Twitter

Différence entre copy et deepcopy

    21 octobre 2022 à 15:45:29

    Bonjour,

    Je suis actuellement débutante en Python (version 3.6.4).

    Je n'ai pas compris la différence entre copy() et deepcopy() dans le cas des listes. Selon la définition pour une liste donnée a, b=copy.copy(a) et c=c.deepcopy(a) on a les id (emplacement mémoire) des éléments de a sont identiques à ceux de b et différent de ceux de c (exemple: id(a[0])=id(b[0]) et id(a[0])!=id(c[0])). Or, j'ai effectué des tests et j'ai trouvé que même id(a[0])=id(c[0]).En plus, lorsque j'effectue une modification sur un élément de la liste a, pas de modification sur la liste b seulement si cet élément est une liste.

    Exemple :

    >>>a[1,2,3,[4]]

    >>> b=copy.copy(a)

    >>> b[3].append(25)

    >>> b

    [1, 2, 3, [4, 25]]

    >>> a

    [1, 2, 3, [4, 25]] 

    or si par exemple a=[1,2,3,4] et b=copy.copy(a), alors toute modification sur l'une des deux chaines n'a pas d'effet sur l'autre.

    Je voudrais savoir le principe de ces deux fonctions de copie.

    Merci d'avance pour votre aide.

    • Partager sur Facebook
    • Partager sur Twitter
      21 octobre 2022 à 17:44:04

      Tu n'as fait que la moitié du test:
      -
      >>> a=[1, 2, 3, [4]]                                                                                                    
      >>> b=deepcopy(a)                                                                                                       
      >>> a                                                                                                                   
      [1, 2, 3, [4]]                                                                                                          
      >>> b                                                                                                                   
      [1, 2, 3, [4]]                                                                                                          
      >>> b[3].append(25)                                                                                                     
      >>> a                                                                                                                   
      [1, 2, 3, [4]]                                                                                                          
      >>> b                                                                                                                   
      [1, 2, 3, [4, 25]]                                                                                                      
      >>>
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        21 octobre 2022 à 20:56:19

        SalmaSalma50 a écrit:

        or si par exemple a=[1,2,3,4] et b=copy.copy(a), alors toute modification sur l'une des deux chaines n'a pas d'effet sur l'autre.

        Je peux me tromper, mais je pense que c'est parce que int est un type 'immutable'.

        Quand tu modifies la liste de type list, tu modifies l'objet, alors que quand tu modifies la valeur de l'entier de type int, tu crées un nouvel objet.

        Pour s'en convaincre, on peut utiliser la fonction native id (https://docs.python.org/3/library/functions.html#id).

        Avec copy():

        >>> a = [1, 2, [3, 4, 5]]
        >>> b = copy.copy(a)
        >>> [id(a[i]) == id(b[i]) for i in range(3)]
        [True, True, True]
        >>> a[0] = 0
        >>> a[2].append(6)
        >>> [id(a[i]) == id(b[i]) for i in range(3)]
        [False, True, True]
        >>> print(a, b)
        [0, 2, [3, 4, 5, 6]] [1, 2, [3, 4, 5, 6]]
        

        Avec deepcopy():

        >>> a = [1, 2, [3, 4, 5]]
        >>> b = copy.deepcopy(a)
        >>> [id(a[i]) == id(b[i]) for i in range(3)]
        [True, True, False]
        >>> a[0] = 0
        >>> a[2].append(6)
        >>> [id(a[i]) == id(b[i]) for i in range(3)]
        [False, True, False]
        >>> print(a, b)
        [0, 2, [3, 4, 5, 6]] [1, 2, [3, 4, 5]]

        -
        Edité par KoaTao 21 octobre 2022 à 23:15:37

        • Partager sur Facebook
        • Partager sur Twitter
          22 octobre 2022 à 1:18:54

          Mon explication est peut-être fausse et teintée de C ... :)
          Quand on fait un copy, pour le dermier item, c'est comme si on recopiait un "pointeur" vers la sous-liste.
          Quand on fait un append, ça parait dans les deux listes car c'est le même pointeur.
          Si on fait un deepcopy, c'est comme si on copiait également la sous-liste dans une nouvelle sous-liste avec un nouveau "pointeur".
          Donc une modification d'un côté n'apparaîtra pas de l'autre côté.

          Ça ressemble un peu à ceci comme idée:
          >>> a=[1,2,3];b=a;a;b                                                                                                   
          [1, 2, 3]                                                                                                               
          [1, 2, 3]                                                                                                               
          >>> a[0]=6;a;b                                                                                                          
          [6, 2, 3]                                                                                                               
          [6, 2, 3]                                                                                                               
          >>> b=a[:];a;b                                                                                                          
          [6, 2, 3]                                                                                                               
          [6, 2, 3]                                                                                                               
          >>> a[0]=99;a;b                                                                                                         
          [99, 2, 3]                                                                                                              
          [6, 2, 3]                                                                                                               
          >>>                                                                                                                     

          -
          Edité par PierrotLeFou 22 octobre 2022 à 1:25:48

          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

          Différence entre copy et deepcopy

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown