Метка: del

Python: все про del

КДПВ

Инструкция del (от англ. delete), как можно понять из названия, нужна чтобы что-то удалять, а именно имена переменных, атрибуты объектов, элементы списков и ключи словарей.

1. Удаление элемента из списка по индексу:

>>> x = [1, 2, 3, 4, 5]
>>> del x[2]
>>> x
[1, 2, 4, 5]

Также можно удалять по срезам. Пример: удаление первых двух элементов:

>>> x = [1, 2, 3, 4, 5]
>>> del x[:2]
>>> x
[3, 4, 5]

Удаление последних n элементов: del x[n:].

Удаление элементов с четными индексами: del x[::2], нечетными: del x[1::2].

Удаление произвольного среза: del x[i:j:k].

Не путайте del x[2] и x.remove(2). Первый удаляет по индексу (нумерация с 0), а второй по значению, то есть находит в списке первую двойку и удаляет ее.

2. Удаление ключа из словаря. Просто:

>>> d = {"foo": 5, "bar": 8}
>>> del d["foo"]
>>> d
{'bar': 8}

А вот строки, байты и сеты del не поддерживают.

3. Удаление атрибута объекта.

class Foo:
    def __init__(self):
        self.var = 10

f = Foo()
del f.var
print(f.var)  # ошибка! 

Примечание: можно через del удалить метод у самого класса del Foo.method, но нельзя удалить метод у экземпляра класса del Foo().methodAttributeError.

4. Что значит удалить имя переменной? Это просто значит, что надо отвязать имя от объекта (при этом если на объект никто более не ссылается, то он будет освобожден сборщиком мусора), а само имя станет свободно. При попытке доступа к этому имени после удаления будет NameError, пока ему снова не будет что-то присвоено.

>>> a = 5
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

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

g = 100
def f():
    global g
    g = 200
    del g  # g останется вне функции
    g = 300  # та же самая глобальная g

f()
print(g) # 300

Чтобы реально удалить глобальную переменную, можно сделать так: del globals()['g'].

В пунктах 1, 2, 3 в качестве имен могут фигурировать выражения и ссылки, так как операции идут над содержимым объектов, а в пункте 4 должно быть строго формальное имя удаляемого объекта.

>>> x = [1, 2, 3]
>>> y = x
>>> del y  # удаляет именно y, но x остается

Еще одна особенность del – она может удалить несколько вещей за раз, если передать в нее кортеж или список объектов на удаление.

x, y, z = 10, 20, [1, 2, 3]
del x, y, z[2]

Пусть задан список из 5 элементов:

x = [1, 2, 3, 4, 5]
del x[2], x[4]

Казалось бы, что будут удалены 2-й и 4-й элементы списка, но это не так! Удаления происходят один за одним, и сначала будет удален 2-й элемент, размер списка уменьшится на 1, а потом будет попытка удалить 4-й элемент, но она будет неудачна – вылетит исключение IndexError, потому что элемента с индексом 4 больше нет, а сам список будет равен [1, 2, 4, 5]. Так что будьте внимательны в подобных ситуациях!

Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈 

Удаление ключа из словаря

Выдирает страницу из словаря

Словарь (dict) – изменяемый тип в Python. Из словаря можно легко удалить ключ оператором del:

>>> d = {"foo":123, "bar":321}
>>> del d["foo"]
>>> d
{'bar': 321}

Что если ключа не окажется в словаре? Ответ: исключение – KeyError:

>>> del d['baz']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'baz'

Конечно, можно сделать так:

if 'baz' in d:
    del d['baz']

Или даже так:

try:
    del d['baz']
except KeyError:
    pass

Однако, есть способ удалить ключ (которого возможно нет) в одну строчку:

d.pop('baz', None)

Обратите внимание, что второй аргумент None обязателен. Кроме того, метод pop вернет удаленный элемент, что может быть полезно в каких-то случаях.

🧙 Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈