A atribuição aumentada em [[Linguagem de programação Python|Python]] é uma forma concisa e eficiente de modificar o valor de uma variável e atribuir o resultado de volta à mesma variável. Ela combina uma operação (aritmética, bit a bit, etc.) com a atribuição, tornando o código mais legível e, em alguns casos, mais performático.
# Como Funciona
Em vez de escrever `x = x + y`, você pode usar a atribuição aumentada `x += y`. Isso se aplica a uma variedade de operadores.
## Exemplos Comuns
Aqui estão os operadores de atribuição aumentada mais utilizados com exemplos:
```python
# Exemplo com números inteiros
a = 5
b = 3
print(f"Valor inicial de 'a': {a}") # 5
# Adição aumentada
a += b # Equivalente a a = a + b (a = 5 + 3)
print(f"Após a += b: {a}") # Saída: 8
# Subtração aumentada
a -= b # Equivalente a a = a - b (a = 8 - 3)
print(f"Após a -= b: {a}") # Saída: 5
# Multiplicação aumentada
a *= b # Equivalente a a = a * b (a = 5 * 3)
print(f"Após a *= b: {a}") # Saída: 15
# Divisão aumentada
a /= b # Equivalente a a = a / b (a = 15 / 3)
print(f"Após a /= b: {a}") # Saída: 5.0 (resultado float)
# Módulo aumentado
a = 10
a %= b # Equivalente a a = a % b (a = 10 % 3)
print(f"Após a %= b: {a}") # Saída: 1
# Exponenciação aumentada
a = 2
a **= b # Equivalente a a = a ** b (a = 2 ** 3)
print(f"Após a **= b: {a}") # Saída: 8
# Divisão inteira aumentada
a = 10
a //= b # Equivalente a a = a // b (a = 10 // 3)
print(f"Após a //= b: {a}") # Saída: 3
```
## Operadores Bit a Bit
Os operadores de atribuição aumentada também funcionam com operações bit a bit:
```python
x = 10 # Binário: 1010
y = 3 # Binário: 0011
print(f"\nValor inicial de 'x': {x}") # 10
# AND bit a bit aumentado
x &= y # Equivalente a x = x & y (1010 & 0011 = 0010)
print(f"Após x &= y: {x}") # Saída: 2
# OR bit a bit aumentado
x = 10
x |= y # Equivalente a x = x | y (1010 | 0011 = 1011)
print(f"Após x |= y: {x}") # Saída: 11
# XOR bit a bit aumentado
x = 10
x ^= y # Equivalente a x = x ^ y (1010 ^ 0011 = 1001)
print(f"Após x ^= y: {x}") # Saída: 9
# Deslocamento à esquerda aumentado
x = 10
x <<= 1 # Equivalente a x = x << 1 (1010 << 1 = 10100)
print(f"Após x <<= 1: {x}") # Saída: 20
# Deslocamento à direita aumentado
x = 10
x >>= 1 # Equivalente a x = x >> 1 (1010 >> 1 = 0101)
print(f"Após x >>= 1: {x}") # Saída: 5
```
# Comportamento com Tipos Mutáveis e Imutáveis
É importante notar a diferença no comportamento da atribuição aumentada entre tipos de dados mutáveis (como listas) e imutáveis (como números, strings e tuplas).
* **Tipos Imutáveis (int, float, str, tuple)**: Para tipos imutáveis, a atribuição aumentada (`a += b`) geralmente resulta na criação de um _novo objeto_ com o valor calculado, e a variável `a` é então reassociada a esse novo objeto. É semanticamente equivalente a `a = a + b`.
```python
num = 5
print(f"ID de num antes: {id(num)}") # Ex: 140736028790080 (o ID pode variar)
num += 3
print(f"ID de num depois: {id(num)}") # Ex: 140736028790144 (ID diferente, novo objeto)
```
* **Tipos Mutáveis (list, dict, set)**: Para tipos mutáveis, a atribuição aumentada pode, em muitos casos, modificar o objeto _no local_ (in-place), sem criar um novo objeto. Isso é feito através de métodos especiais como `__iadd__` (para `+=`), `__imul__` (para `*=`), etc.
```python
lista_a = [1, 2]
lista_b = [3, 4]
print(f"ID de lista_a antes: {id(lista_a)}") # Ex: 234567890123 (o ID pode variar)
lista_a += lista_b # Isso chama lista_a.__iadd__(lista_b), modificando lista_a in-place
print(f"ID de lista_a depois: {id(lista_a)}") # Ex: 234567890123 (ID o mesmo)
print(lista_a) # Saída: [1, 2, 3, 4]
# Comparar com a criação de um novo objeto:
# lista_c = [1, 2]
# lista_d = [3, 4]
# print(f"ID de lista_c antes: {id(lista_c)}")
# lista_c = lista_c + lista_d # Isso cria uma nova lista e reatribui
# print(f"ID de lista_c depois: {id(lista_c)}") # ID diferente
# print(lista_c) # Saída: [1, 2, 3, 4]
```
Essa distinção é crucial para entender como as referências e a memória são gerenciadas em [[Linguagem de programação Python|Python]], especialmente ao trabalhar com objetos grandes ou em cenários onde a identidade do objeto é importante.
# Vantagens
* **Concisão**: Reduz a verbosidade do código, tornando-o mais compacto.
* **Legibilidade**: Torna a intenção do código mais clara, especialmente para operações repetitivas na mesma variável.
* **Eficiência (para tipos mutáveis)**: Ao modificar objetos no local, pode evitar a criação desnecessária de novos objetos, o que pode ser mais eficiente em termos de memória e desempenho.
:: **Referência** :: [PEP 577 – Expressões de Atribuição Aumentada](https://peps.python.org/pep-0577/)