вторник, 1 сентября 2020 г.

ЛМНты Python, 76 - 80

>>> Разоблачение operator.itemgetter

Боюсь, последний пример с функцикй itemgetter непонятен или не нагляден.

Функция itemgetter возвращает функцию (точнее, callable объект), которая принимает на вход последовательность и возвращает элемент последовательности с нужным индексом:

>>> from operator import itemgetter
>>>
>>> getitem2 = itemgetter(2)
>>> getitem2(['a','b','c'])
'c'
>>> itemgetter(0)(['a','b','c'])
'a'
>>> itemgetter(1)(['a','b','c'])
'b'

>>> Почти как sorted

В отличие от функции sorted, метод sort не создает новый список, а упорядочивает последовательность, для которой вызывается:

>>> a = [2,5,1,3,7,4,9,8,6]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Как и функция, метод имеет именованные параметры key и reverse. Воспользуемся ими, но сначала переставим элементы случайным образом:

>>> from random import shuffle
>>> shuffle(a)
>>> a
[1, 7, 3, 2, 9, 5, 6, 4, 8]
>>> a.sort(key=lambda e: e%2)
>>> a
[2, 6, 4, 8, 1, 7, 3, 9, 5]
>>> a.sort(reverse=True)
>>> a
[9, 8, 7, 6, 5, 4, 3, 2, 1]

>>> Метод copy

Вспомним, что операция присваивания не копирует объект, а только связывает с именем указатель на объект:

>>> a = [1, 2, 3]
>>> b = a
>>> a is b
True
>>>
>>> b[0] = -1
>>> b
[-1, 2, 3]
>>> a
[-1, 2, 3]

Для того, чтобы получить копию объекта, нужно воспользоваться методом copy:

>>> c = b.copy()
>>> c is b
False
>>>
>>> c[1] = -2
>>> c
[-1, -2, 3]
>>> b
[-1, 2, 3]

>>> Передача аргумента по значению

Передача аргументов при вызове функции приводит к тому, что имя параметра начинает ссылаться на объект, идентифицированнй аргументом (как при присваивании):

>>> a = [1, 2, 3]
>>>
>>> def fun(x):
...     print(x is a)
...     x[0] = -1
...     print(x)
...
>>> fun(a)
True
[-1, 2, 3]
>>> a
[-1, 2, 3]

Для передачи копии списка или другого изменяемого объекта нужно воспользоваться методом copy – и тем самым имитировать передачу аргумента по значению:

>>> a = [1, 2, 3]
>>>
>>> fun(a.copy())
False
[-1, 2, 3]
>>> a
[1, 2, 3]

>>> Что нельзя скопировать

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

>>> (1, 2, 3).copy()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'copy'

У изменяемых объектов имеется метод copy, у неизменяемых – отсутствует:

>>> classes = (
...     list,
...     dict,
...     set,
...     tuple,
...     int,
...     float
... )
>>>
>>> for c in classes:
...     print(c.__name__, 'copy' in dir(c))
...
list True
dict True
set True
tuple False
int False
float False

См. также лмнт Единственный и неизменный.

Комментариев нет:

Отправить комментарий