Apuntes_Python/02_conceptos/20_shallow_vs_deep_copying/README.md

196 lines
3.7 KiB
Markdown
Raw Normal View History

2022-12-24 22:41:20 -03:00
# Copia de elementos
- [Copia de elementos mutables con el modulo 'copy'](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/20_shallow_vs_deep_copying#copia-lista)
- [Diferencias entre copia superficial y copia profunda (shallow & deep copying)](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/20_shallow_vs_deep_copying#copia-superficial-shallow-y-profunda-deep)
- [Copia de Clases y Objetos](https://gitea.kickto.net/devfzn/Apuntes_Python/src/branch/master/02_conceptos/20_shallow_vs_deep_copying#copiando-clases)
----
#### Copia
Nueva variable, con la misma referencia
```python
orig = 5
copia = orig
```
#### Copia
Nueva variable con otra referencia
```python
copia = 6
print(orig,copia)
# 5 6
```
#### Copia lista
Asigna la misma referencia a nueva variable
```python
orig = [0, 1, 2, 3]
copia = orig
copia[0] = -10
print(orig, copia)
# [-10, 1, 2, 3] [-10, 1, 2, 3]
```
#### lista.copy()
nueva variable, nueva referencia
```python
copia2 = orig.copy()
orig[0] = 9
print(orig, copia2)
# [9, 1, 2, 3] [-10, 1, 2, 3]
```
## Modulo copy
La diferencia entre copia ***superficial*** y ***profunda***, es solo relevante para objetos
compuestos (objetos que contienen otros objetos), como **listas**, **clases** o **instancias**
* **copia superficial:** construye un nuevo objeto compuesto, y luego (a medida de lo posible), inserta
referencias en los objetos encontrados en el original.
* **copia profunda** construye un nuevo un nuevo objeto, y luego, recursivamente, inserta copias de
los objetos que se encuentran en el original.
[copy-doc](https://docs.python.org/3/library/copy.html)
## Copia superficial (shallow) y profunda (deep)
```python
import copy
```
**Shallow copy**:
- Un nivel de profundidad, solo referencias de
objetos hijos anidados. `x = copy.copy(y)`
**Deep copy**:
- Copia completamente independiente `x = copy.deepcopy(y)`
### Superficial
```python
import copy
orig = [0, 1, 2, 3, 4]
copia = orig
copia = copy.copy(orig)
copia[0] = -10
print(copia)
# [-10, 1, 2, 3, 4]
print(orig)
# [0, 1, 2, 3, 4]
```
Otras formas de copiar listas superficialmente
```python
copia = orig.copy()
copia = list(orig)
copia = orig[:]
```
Solo un solo nivel de profundidad
```python
orig = [[0,1,2,3],[4,5,6,7]]
copia = orig.copy()
copia[0][1] = -10
print(copia)
# [[0, -10, 2, 3], [4, 5, 6, 7]]
print(orig)
# [[0, -10, 2, 3], [4, 5, 6, 7]]
```
### Copia Profunda
```python
import copy
orig = [[0,1,2,3],[4,5,6,7]]
copia = copy.deepcopy(orig)
copia[0][1] = -10
print(copia)
# [[0, -10, 2, 3], [4, 5, 6, 7]]
print(orig)
# [[0, 1, 2, 3], [4, 5, 6, 7]]
```
## Copiando clases
Copia superficial
```python
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
p1 = Persona('Zafiro', 82)
p2 = p1
p2.edad = 28
print(p2.edad) # 28
print(p1.edad) # 28
```
Copia superficial, solo un vivel de profundidad
```python
import copy
p2 = copy.copy(p1)
p2.edad = 46
print(p2.edad) # 46
print(p1.edad) # 28
class Compania:
def __init__(self, jefe, empleado):
self.jefe = jefe
self.empleado = empleado
p1 = Persona('Norberto', 61)
p2 = Persona('Zerafin', 16)
compania = Compania(p1, p2)
compania_copia = copy.copy(compania)
compania_copia.jefe.edad = 36
# copia superficial, solo un nivel mas de profundidad
# apunta a la misma referencia en este nivel.
print(compania_copia.jefe.edad)
# 36
print(compania.jefe.edad)
# 36
```
Copia profunda, independiente
```python
compania = Compania(p1, p2)
compania_copia = copy.deepcopy(compania)
compania_copia.jefe.edad = 64
print(compania_copia.jefe.edad)
# 64
print(compania.jefe.edad)
# 36
```