Если вы новичок в Python, возможно, вы слышали о терминах изменяемый или неизменяемый на лекциях, курсах и т. Д. Знание этого может потенциально сэкономить вам часы на отладку определенных побочных эффектов, возникающих в результате изменчивости!

В двух словах о изменчивости и неизменности

Говоря простым языком, что-то изменяемое может быть изменено, а что-то, что является неизменным, не может быть изменено после того, как оно было определено.

Неизменяемые типы данных в Python

  1. Числа (int, float, complex)
  2. Строки (str) - это, по сути, неизменяемый список
  3. Логические значения (bool)

Изменяемые типы данных в Python

  1. Списки
  2. Словари
  3. Наборы

Пример изменчивости

Допустим, у нас есть список

list1 = ["apple", "orange", "pear"]

И мы хотим заменить "apple" на "pineapple". Мы можем просто сделать это:

list1[0] = "pineapple"
print(list1) # list1 will be ["pineapple", "orange", "pear"] 

То же самое со словарями и наборами - мы можем использовать соответствующие методы для изменения самого исходного объекта

dict1 = {"apple":4, "orange":5, "pear":6}
set1 = set(["apple", "orange", "pear"])
dict1["apple"] = 100 # changing 4 to 100
set1.add("pineapple") # adding pineapple to set1
# dict1 will be {"apple":100, "orange":5, "pear":6}
# set1 will be {"apple", "orange", "pear", "pineapple"}

Пример неизменности

Допустим, у нас есть строка fruit = "apple", и по какой-то причине мы хотим заменить "a" на "b". Если мы попробуем это сделать, то увидим ошибку:

fruit = "apple"
fruit[0] = "b"

Вместо этого единственный способ заставить переменную fruit принимать значение "bpple" - это переназначить ее.

fruit = "bpple"
#or
fruit = fruit.replace("a", "b")
# in both cases, fruit becomes "bpple"

Примечание: метод .replace возвращает копию строки с заменой "a" на "b", но исходная переменная остается неизменной, поскольку строки неизменяемы.

fruit = "apple"
fruit2 = fruit.replace("a", "b")
print(fruit) # apple (this remain unchanged)
print(fruit2) # bpple

Таким образом, единственный способ изменить неизменяемый тип данных - полностью переназначить переменную.

Изменчивость и функции

Допустим, у нас есть существующий список и функция, изменяющая его. Если мы вызовем нашу функцию, сам наш список будет изменен функцией, поскольку списки являются изменяемыми типами данных.

list1 = ["apple", "orange", "pear"]
def mutate(list1):
    list1[0] = "durian"
    print(list1)
mutate(list1) # prints ["durian", "orange", "pear"]
print(list1) # prints ["durian", "orange", "pear"

Для неизменяемых типов данных это работает немного по-другому:

tuple1 = ("apple", "orange", "pear")
def mutate(tuple1):
    tuple1 = ("durian",) + tuple1[1:] # we can only do it this way
    print(tuple1)
mutate(tuple1) # ("durian", "orange", "pear")
print(tuple1) # ("apple", "orange", "pear")

Здесь кортеж - это неизменяемый список - мы не можем изменить его, кроме как полностью переназначить его

tuple1 = ("durian", "orange", "pear")
# reassigning the variable tuple1 is the only way here

Неизменяемость и словари

Короче говоря, ключами словаря могут быть только неизменяемые типы данных.

dict1 = {
    [1,2]: "some value",
    [3,4]: "another value"
}
# this will raise an error

Если мы попытаемся сделать это, мы получим ошибку, поскольку мы пытаемся использовать изменяемый тип данных list в качестве ключа словаря. Если нам действительно нужно несколько значений в качестве ключа словаря, мы должны использовать неизменяемые типы данных, такие как кортежи:

dict1 = {
    (1,2): "some value",
    (3,4): "another value"
}
# this is ok

Это относится и к наборам - мы можем помещать в наборы только неизменяемые значения!

Заключение

Надеюсь, это поможет уменьшить потенциальные побочные эффекты (ошибки) непонятного понимания изменчивости в Python!

Больше контента на plainenglish.io