Лутц М. - Изучаем Python (1077325), страница 64
Текст из файла (страница 64)
Допускается присваивать кортеж значений списку переменных, строки символов — кортежу переменных и т. д. В любом случае интерпретатор свяжет элементы последовательности справа с переменными в последовательности слева согласно их позициям в направлении слева направо: »> ~в, Ь, с) = (1, 2, 3) № Кортем аначений присваивается списку переменных »>в, с (1, 3) »> (в, Ь, с) = "АВС" »>в, с СА', 'С ) № Строка симеонов присваивается кортежу переменных С технической точки зрения в правой части инструкции присваивания последовательностей допускается указывать не только последовательности, но и любые объекты, обеспечивающие возможность итераций по элементам. Эту, еще более общую концепцию, мы будем рассматривать в главах 13 и 17. Обратите внимание: в третьей инструкции этого примера в действительности присутствует два кортежа, просто мы опустили охватывающие их круглые скобки.
Интерпретатор Руц)топ сопоставляет значения элементов кортежа справа от оператора присваивания с переменными в кортеже слева и выполняет присваивание значений в одной инструкции. Операция присваивания кортежей дает возможность использовать прием, который представлен в упражнениях ко второй части книги. Так как в процессе выполнения инструкции интерпретатор создает временный кортеж, где сохраняются оригинальные значения переменных справа, данная форма присваивания может использоваться для реализации обмена значений переменных без создания временной переменной — кортеж справа автоматически запоминает предыдущие значения переменных: 296 Дополнительные варианты инструкции присваивания последовательностей Одно замечание — даже при том, что допускается смешивать разные типы последовательностей по обе стороны оператора =, обе последова- тельности должны иметь одно и пзо же число элементов, в противном случае мы получим сообщение об ошибке: >» втг1пц = 'ЗРАИ' »> а, Ь, с, б = всг1пц № Одинаковое число злементое с обеих сторон »>а, б ('8', 'М') »> а, Ь, с = втг1пц № В протиеном слу~ае еыеодится сообщение об ошибке .
текст сообщения об ошибке опущен .. На1оеЕггог; 1оо папу на1оез 1о спраск (Перевод, На1сеЕггог; слишком много распакованных значений) В общем случае нам необходимо получить срез. Существует несколько вариантов извлечения среза, чтобы исправить дело: »> а, Ь, о = втг1пц[0], втг1пц[13, втг1пц[2:] № Элементы и срез »>а, Ь,с ('8', 'Р', 'АМ') »> а, Ь, с = 11в1(втг1пц[:2]) + [втг1пц[2:]] № Срезы и конкатензпия »>а, Ь,с ('8', 'Р', 'АМ') № То ме самое, только проще »> (а, Ь), с = в1г1пц[:23, в1г1пц[2:3 № Вломенные последовательности »>а, Ь,с ( 8', 'Р', 'АМ') Последний пример демонстрирует, что мы можем присваивать даже вложенные последовательности, и интерпретатор распаковывает их части в соответствии с их представлением, как и ожидается.
В данном случае выполняется присваиванис корте>гяа из двух элементов, где первый элемент — это вложенная последовательность (строка), что точно соответствует следующему случаю: »> ((а, Ь), с) - "('ЗР', 'АИ') № Связывание производится е соответствии »>а, Ь,с № с Формой и местополоиениеи ('8', 'Р', 'АМ') Интерпретатор связывает первую строку справа ('8Р') с первым кортежем слева ((а, Ь)), присваивая каждому его элементу по одному символу, а затем выполняет присваивание второй строки целиком ('АМ') переменной с. В этом случае вложенная последовательность слева, имеющая форму объекта, должна соответствовать объекту справа.
»> а, Ь = в1г1пц['23 »> с - "всг1пц[2:3 »>а, ь,с (8, Р, АМ) Глава 11. Присваивание, выражения и рпп1 297 Инструкции присваивания Присваивание вложенных последовательностей — это достаточно сложная операция, которая редко встречается на практике, но такой способ присваивания может оказаться удобным для присваивания части структуры данных известной формы. Например, данный прием может также использоваться в списках аргументов функций, потому что передача аргументов выполняется присваиванием (как будет показано в следующей части книги). Кроме того, операция присваивания последовательности с распаковкой дает начало еще одному распространенному обороту программирования на языке Ру(акоп — присваиванию последовательности целых чисел множеству переменных: »> гез, Огееп, Мое = гапее(3) »> гее, В(ое (О, 2) В этом примере три переменные инициализируются целочисленными значениями О, 1 и 2 соответственно (это эквивалент леречислимегх типов данных в языке Ру()топ, которые, возможно, вам приходилось встречать в других языках программирования).
Чтобы понять происходящее, вы должны знать, что встроенная функция гапре генерирует список последовательных целых чисел: »> галде(3) № лолройуйте )тат(галде(З)) а Руглол 3.0 [О, 1, 2) Поскольку функция гвпре часто используется в циклах тог, мы еще поговорим о ней в главе 13. Другой случай применения операции присваивания кортежей — разделение последовательности на начальную и остальную части в циклах, как показано ниже: »> [ = [1, 2, 3, 4) >» еяые Ы (гопы [ = [[О), О[1:) рг(пт Ггопт, 1 [2, 3, 4) 2 [3, 4) 3 [4) 4 [) Присваивание кортежа в цикле здесь можно было бы заменить двумя следующими строками, но часто бывает удобнее объединить их в одну строку: Ггопт = ([О) ь = [[1;) Обратите внимание: в этом примере список используется в качестве стека — структуры данных, поведение которой реализуют методы списков зррепр и рор.
В данном случае эффект, который дает операция присваивания кортежа, можно было бы получить инструкцией г гас 1 = 'с. рор(0), 298 Глвва11. Присваивание, выражения и рпп1 но это будет операция непосредственного изменения объекта. О циклах нп[]е и о других (часто лучших) способах обхода последовательностей с помощью циклов Гог вы узнаете больше в главе 13. Групповое присваивание При групповом присваивании объект, расположенный справа, присваивается всем указанным переменным. В следующем примере трем переменным а, Ь и с присваивается строка ' враз ': »> а = Ь = с = 'враз' »>а,Ь,с ['враз', 'врав', 'срав') Эта инструкция эквивалентна (но записывается компактнее) следующим трем инструкциям присваивания: »> с = 'враз' »> Ь = с »> а = Ь Групповое присваивание и разделяемые ссылки Имейте в виду, что в этом случае существует всего один объект, разделяемый всеми тремя переменными (все они указывают на один и тот же объект в памяти), Такой способ присваивания хорошо подходит для неизменяемых объектов, например для инициализации нескольких счетчиков нулевым значением (не забывайте, что в языке РуЖоп переменная должна быть инициализирована, прежде чем к ней можно будет обратиться, поэтому вам всегда придется устанавливать начальные значения в счетчиках, прежде чем они смогут использоваться для счета): »> з Ь = О »> Ь = Ь + 1 »>а, Ь [О, 1) Здесь изменение переменной Ь затронет только переменную Ь, потому что числа не допускают возможность непосредственного изменения.
Если присваиваемый объект является неизменяемым, совершенно неважно, как много ссылок на него будет создано. Но, как обычно, следует проявлять осторожность, выполняя присваивание переменным изменяемых объектов, таких как списки или словари: »>а Ь=[] »> ь.арресс[42) »>а, Ь [[42], [42]) На этот раз, поскольку а и Ь ссылаются на один и тот же объект, непосредственное добавление значения к объекту через переменную Ь будет воздействовать и на переменную в. В действительности это всего лишь другой пример взаимовлияния разделяемых ссылок, с которым мы 299 Инструкции присваивания впервые встретились в главе 6.
Чтобы избежать этой проблемы, ини- циализацию изменяемыми объектами следует производить в отдель- ных инструкциях, чтобы в каждой из них создавался новый пустой объект с помощью отдельных литеральных выражений: »> в = [] »> Ь = [] »> Ь.вррепц[42) »>в, Ь [[], [42]) Х=Х+У Х += У № Традиционная форма записи № Новая, комбинированная форма записи Таблица 11.2.
Комбинированные инструкции присваивания Х+=У Х = У Хь=у Х 8= У Х -= У Х/=У Х*=У Х [=У Х»= У Х //= У Х <<= У Комбинированные операции присваивания существуют для любого поддерживаемого двухместного оператора. Например, ниже приводит- ся два способа прибавления 1 к переменной: »> х = 1 »>х=х+1 № Традиционная форма записи »> х 2 »> х+= 1 »> х 3 № Допояняоцая Если дополняющую форму применить к строкам, будет выполнена операция конкатенации. Таким образом, вторая строка ниже эквива- лентнаболеедлиннойинструкции8 = 8 в "ЯРАМ": »> 8 = врвв" »> 8 += "8РАИ" »> 8 'зрав8РАМ' № Внпопняется операция конкатенации Как показано в табл.
11.2, для каждого двухместного оператора (т. е. для оператора, слева и справа от которого располагаются значения, участвующие в операции) в языке Ру$]топ существует своя инструкция Дополняющее присваивание Начиная с версии Ру[[топ 2.0, в языке появился набор дополнительных инструкций присваивания, перечисленных в табл. 11.2. Известные как инструкции дополняющего присваивания и заимствованные из языка С, они по существу являются лишь более компактной формой записи. Они комбинируют в себе выражение и операцию присваивания. Например, следующие две формы записи практически эквивалентны: Глава 11.
Присваивание, выражения и рпп1 дополняющего присваивания. Например, инструкция Х *= 'т' выполняет умножение и присваивание, Х »= у — сдвиг вправо и присваивание, и т. д. Инструкция Х //= У (деление с округлением вниз) была добавле- на в версии РуФ]топ 2,2. >» [ = [1, 2] »> [ = [+ [3] »> [1, 2, 3] »> Ь,арреяб(4) »> [1. 2, 3, 4] Ф Конкатенация: более иедленная и Более бистроя, но изиеняет сяи объект А чтобы добавить несколько элементов, мы можем либо снова выпол- нить операцию конкатенации, либо вызвать метод ехгепб »> Ь = Ь + [5, 6] »> [1, 2, 3, 4, 5, 6] »> ы ехтеяз ([?, 8]) и Конкатенация: более иедленная Л Более бистрац но изиеняет саи объект Программисты С/С++, конечно, заметят, что несмотря на появление в языке Руъ)топ таких инструкций, как Х «=т, в нем до сих пор отсутствуют операторы инкремента и декремента (например, Х+«, --Х). Однако эти операторы вообще не соответствуют модели языка Руъпоп, в котором отсутствует возможность непосредственно изменять неизменяемые объекты, такие как числа.
Как предлагалось в главе 6, для этого также можно было бы использовать операцию присваивания срезу (например, [[1ея( ъ): ] = [11, 12, 13]), но этот прием работает практически так же, как метод ехтЕЯО. Дополняющие присваивания обладают следующими преимуществами ° Уменьшается объем ввода с клавиатуры. Нужно ли мне продолжать? ° Левая часть инструкции должна быть получена всего один раз.