Каковы варианты клонирования или копирования списка в Python?
В Python 3 мелкая копия может быть выполнена с помощью:
a_copy = a_list.copy()
В Python 2 и 3 вы можете получить мелкую копию с полным фрагментом оригинала:
a_copy = a_list[:]
Объяснение
Существует два семантических способа копирования списка. Неглубокая копия создает новый список тех же объектов, глубокая копия создает новый список, содержащий новые эквивалентные объекты.
Короткая копия списка
Неглубокая копия копирует только сам список, который является контейнером ссылок на объекты в списке. Если объекты, содержащиеся в них, являются изменяемыми и один из них изменен, это изменение будет отражено в обоих списках.
Существуют разные способы сделать это в Python 2 и 3. Пути Python 2 также будут работать в Python 3.
Python 2
В Python 2 , идиоматический способ создания мелкой копии списка состоит из полного фрагмента оригинала:
a_copy = a_list[:]
Вы также можете выполнить одно и то же, передав список через конструктор списка,
a_copy = list(a_list)
, но использование конструктора менее эффективно:
>>> timeit >>> l = range(20) >>> min(timeit.repeat(lambda: l[:])) 0.30504298210144043 >>> min(timeit.repeat(lambda: list(l))) 0.40698814392089844
Python 3
В Python 3 списки получают метод
list.copy
:a_copy = a_list.copy()
В Python 3.5:
>>> import timeit >>> l = list(range(20)) >>> min(timeit.repeat(lambda: l[:])) 0.38448613602668047 >>> min(timeit.repeat(lambda: list(l))) 0.6309100328944623 >>> min(timeit.repeat(lambda: l.copy())) 0.38122922903858125
Создание другого указателя делает not сделать копию
Используя new_list = my_list, тогда изменяет new_list каждый раз, когда изменяется my_list. Почему это?
my_list
- это просто имя, которое указывает на фактический список в памяти. Когда вы скажетеnew_list = my_list
, что вы не делаете копию, вы просто добавляете другое имя, указывающее на этот исходный список в памяти. У нас могут быть подобные проблемы, когда мы делаем копии списков.>>> l = [[], [], []] >>> l_copy = l[:] >>> l_copy [[], [], []] >>> l_copy[0].append('foo') >>> l_copy [['foo'], [], []] >>> l [['foo'], [], []]
Список - это всего лишь массив указателей на содержимое, поэтому мелкая копия просто копирует указатели, поэтому у вас есть два разных списка, но они имеют одинаковое содержимое. Чтобы сделать копии содержимого, вам нужна глубокая копия.
Глубокие копии
Чтобы сделать глубокую копию списка в Python 2 или 3, используйте
deepcopy
в модулеcopy
:import copy a_deep_copy = copy.deepcopy(a_list)
Чтобы продемонстрировать, как это позволяет нам создавать новые под-списки:
>>> import copy >>> l [['foo'], [], []] >>> l_deep_copy = copy.deepcopy(l) >>> l_deep_copy[0].pop() 'foo' >>> l_deep_copy [[], [], []] >>> l [['foo'], [], []]
Итак, мы видим, что глубокий скопированный список - это совсем другой список из оригинала. Вы можете перевернуть свою собственную функцию, но не надо. Вероятно, вы создадите ошибки, которых иначе не было бы, используя функцию глубокой печати стандартной библиотеки.
Не использовать
eval
Вы можете видеть, что это используется как способ to deepcopy, но не делайте этого:
problematic_deep_copy = eval(repr(a_list))
- Это опасно, особенно если вы оцениваете что-то из источника, которому вы не доверяете.
- Это не надежный, если подэлемент, который вы копируете, не имеет представления, которое может быть доказано для воспроизведения эквивалентного элемента.
- Он также менее эффективен.
В 64-битном Python 2.7:
>>> import timeit >>> import copy >>> l = range(10) >>> min(timeit.repeat(lambda: copy.deepcopy(l))) 27.55826997756958 >>> min(timeit.repeat(lambda: eval(repr(l)))) 29.04534101486206
на 64-битном Python 3.5:
>>> import timeit >>> import copy >>> l = list(range(10)) >>> min(timeit.repeat(lambda: copy.deepcopy(l))) 16.84255409205798 >>> min(timeit.repeat(lambda: eval(repr(l)))) 34.813894678023644
Для Xcode 9:
Закрыть Xcode.
Open Xcode: теперь ваша информация о проекте покажите название языка с языком разработки рядом с ним.
откройте свою цель -> info -> измените «локальный регион разработки локализации» на ваш язык
В файле .xcodeproj вашего проекта найдите строку developmentRegion
. Предположительно, сейчас он говорит «английский». Если вы измените его на «испанский», Xcode 6 должен распознать испанский язык языка локализации вашего проекта по умолчанию на вкладке «Информация», если вы добавите «испанский» в список.
Вы можете узнать больше о эту тему в http://eschatologist.net/blog/?p=224
Вот как вы можете это сделать:
Info.plist
измените область разработки на язык, на котором вы хотите быть основным языком. Обратите внимание, что свойство немного неверно, потому что его значение должно быть кодом языка (с необязательным кодом страны), а не кодом региона или страны. projectname.xcodeproj/project.pbxproj
и выполните поиск developmentRegion
. Вы должны увидеть строку типа developmentRegion = English;
. Измените это, чтобы ссылаться на тот же язык, который вы вложили в ваш файл Info.plist
. Вот пример результата для меня, использующего fr
в качестве базового языка:
developmentRegion = francais
или developmentRegion = fr
?
– Flimm
3 November 2016 в 13:28
knownRegions
(в файле .pbxproj), чтобы он отображал свойство в настройках проекта.
– Patrick Pijnappel
13 December 2016 в 15:54
knownRegions
достаточно, чтобы он отображался в списке «Локализаторы», без необходимости вашего первого шага, который (по крайней мере, на Xcode 8.3 .2) невозможно выполнить, не проверяя хотя бы один файл и добавляя, возможно, нежелательный файл строк локализации в ваш проект.
– Ultimecia
4 May 2017 в 08:57