Есть ли разница между и при копировании списка?

Мы можем (неглубоко) скопировать list , используя [:] :

 l = [1, 2, 3] z1 = l[:] 

Мы также можем (мелкой) скопировать его с помощью [::] :

 z2 = l[::] 

и теперь z1 == z2 будет True . Я понимаю, как эти срезы работают после прочтения ответов в нотации фрагмента объяснения Python .

Но, мой вопрос, есть ли разница между этими двумя внутренне? Является ли более эффективным, чем другое, при копировании или делает то же самое?

2 Solutions collect form web for “Есть ли разница между и при копировании списка?”

Абсолютно никакой разницы между ними, по крайней мере, на Python 3 . Вы можете проверить байт-код, созданный для каждого из них, используя dis.dis если хотите:

 l = [1, 2, 3, 4] 

Байт-код, испускаемый для l[:] :

 from dis import dis dis('l[:]') 1 0 LOAD_NAME 0 (l) 3 LOAD_CONST 0 (None) 6 LOAD_CONST 0 (None) 9 BUILD_SLICE 2 12 BINARY_SUBSCR 13 RETURN_VALUE 

в то время как байт-код, испускаемый для l[::] :

 dis('l[::]') 1 0 LOAD_NAME 0 (l) 3 LOAD_CONST 0 (None) 6 LOAD_CONST 0 (None) 9 BUILD_SLICE 2 12 BINARY_SUBSCR 13 RETURN_VALUE 

как вы можете видеть, они точно такие же . Оба загружают несколько None (два LOAD_CONSTS ) для значений start и stop используемых для создания фрагмента ( BUILD_SLICE ) и применяют его. None них не является значением по умолчанию для них, как указано в документах для slices в иерархии стандартного типа :

Специальные атрибуты только для чтения: startlower граница; stop – верхняя граница; step – это значение step ; каждый из них является None если его опущено. Эти атрибуты могут иметь любой тип.

Используйте [:] , это меньше нажатий клавиш.


На самом деле интересно отметить, что в Python 2.x генерируемый байт-код отличается и из-за меньших команд для l[:] он может быть немного более результативным:

 >>> def foo(): ... l[:] ... >>> dis(foo) 2 0 LOAD_GLOBAL 0 (l) 3 SLICE+0 4 POP_TOP 5 LOAD_CONST 0 (None) 8 RETURN_VALUE 

Хотя для l[::] :

 >>> def foo2(): ... l[::] ... >>> dis(foo2) 2 0 LOAD_GLOBAL 0 (l) 3 LOAD_CONST 0 (None) 6 LOAD_CONST 0 (None) 9 LOAD_CONST 0 (None) 12 BUILD_SLICE 3 15 BINARY_SUBSCR 16 POP_TOP 17 LOAD_CONST 0 (None) 20 RETURN_VALUE 

Несмотря на то, что я не приурочил их (и я не буду, разница должна быть крошечной), кажется, что из-за просто требуемых инструкций l[:] может быть немного лучше.


Это сходство, конечно, не существует только для списков ; он применяется ко всем последовательностям в Python:

 # Note: the Bytecode class exists in Py > 3.4 >>> from dis import Bytecode >>> >>> Bytecode('(1, 2, 3)[:]').dis() == Bytecode('(1, 2, 3)[::]').dis() True >>> Bytecode('"string"[:]').dis() == Bytecode('"string"[::]').dis() True 

аналогично для других.

В разделе 6.3.2 «Подписки» на языке языка Python внутреннее выражение для последовательности должно оцениваться как целым числом, так и срезом. Оба эти примера производят один и тот же срез и поэтому идентичны. Есть также множество других срезов, которые имеют одинаковый эффект, явно указывая значения по умолчанию ( start=0 , stop=len(sequence) или more, step=1 ).

  • Установить значение первого элемента в разрезе в python pandas
  • Какова точка зрения в пандах, если не определено, возвращает ли операция индексирования представление или копию?
  • Улучшение чистого первичного сита Python по формуле повторения
  • Как я могу нарезать каждый элемент массива numpy строк?
  • Numpy - нарезание 2d строк или столбцов из массива
  • изменять размер с усреднением или повторять массив numd 2d
  • Хранить многомерный массив массива numpy с newaxis для объекта
  • Почему назначение двурядных массивов numpy не работает?
  • как получить последнюю часть строки перед определенным символом?
  • разрезающая разреженная (scipy) матрица
  • itertools.islice - эффективный выбор списка
  • Python - лучший язык программирования в мире.