문제

깊은 복사본과 얕은 복사본의 차이점은 무엇입니까?

도움이 되었습니까?

해결책

얕은 사본은 가능한 한 적게 복제합니다. 컬렉션의 얕은 사본은 요소가 아닌 컬렉션 구조의 사본입니다. 얕은 사본을 사용하면 두 개의 컬렉션이 이제 개별 요소를 공유합니다.

깊은 사본은 모든 것을 복제합니다. 컬렉션의 딥 카피는 원래 컬렉션의 모든 요소가 복제 된 두 개의 컬렉션입니다.

다른 팁

너비 대 깊이; 객체를 루트 노드로 참조 나무로 생각하십시오.

얕은:

Before Copy Shallow Copying Shallow Done

변수 a와 b는 B가 A에 할당 될 때 두 가지 변수가 동일한 메모리 영역을 참조 할 때 다른 메모리 영역을 나타냅니다. 내용물에 대한 나중에 수정은 내용을 공유하므로 다른 내용에 즉시 반영됩니다.

깊은:

Before Copy Deep Copying Deep Done

변수 a와 b는 B가 메모리 영역의 값에 할당 될 때 다른 메모리 영역을 나타냅니다. 나중에 내용물에 대한 이후 수정은 A 또는 B에 고유하게 유지되고; 내용은 공유되지 않습니다.

간단히 말해서, 무엇이 무엇을 가리키는지에 따라 다릅니다.얕은 복사본에서 객체 B는 메모리에서 객체 A의 위치를 ​​가리킵니다.딥 카피에서는 객체 A의 메모리 위치에 있는 모든 항목이 객체 B의 메모리 위치에 복사됩니다.

이 위키 기사에는 훌륭한 다이어그램이 있습니다.

http://en.wikipedia.org/wiki/Object_copy

특히 iOS 개발자의 경우 :

만약에 B a 얕은 사본A, 그런 다음 원시 데이터의 경우와 같습니다 B = [A assign]; 그리고 물체의 경우와 같습니다 B = [A retain];

B 및 동일한 메모리 위치의 지점

만약에 B a 딥 카피A, 그런 다음 같습니다 B = [A copy];

B 및 다른 메모리 위치에 대한 지점

b 메모리 주소는 A와 동일합니다

B는 A와 동일한 내용을 가지고 있습니다

다음 이미지를 고려하십시오

enter image description here

예를 들어 Object.memberWiseclone a 얕은 복사 링크

그리고 사용 ICLONEBLE 당신이 얻을 수있는 인터페이스 깊은 설명대로 복사하십시오 여기

얕은 사본 : 멤버 값을 한 개체에서 다른 개체로 복사합니다.

딥 카피 : 멤버 값을 한 개체에서 다른 개체로 복사합니다.
모든 포인터 객체는 복제되고 깊은 복사됩니다.

예시:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)

여기서 짧고 이해하기 쉬운 답을 보지 못했습니다. 그래서 시도해 볼게요.

얕은 사본을 사용하면 소스가 가리키는 객체도 대상으로 가리 킵니다 (참조 된 객체가 복사되지 않도록).

딥 카피를 사용하면 소스가 가리키는 모든 객체가 복사되고 사본은 대상으로 가리 킵니다 (이제 각 참조 된 객체의 2 개가 있습니다). 이것은 물체 트리를 되풀이합니다.

쉽게 이해하기 위해이 기사를 따를 수 있습니다.https://www.cs.utexas.edu/~scottm/cs307/handouts/deepcopying.htm


얕은 사본 :

Shallow Copy


딥 카피 :

Deep Copy

{두 개체를 상상해보십시오 : A와 B는 같은 유형의 A와 B (C ++와 관련하여) A와 DEEP 복사 A를 B로 생각하고 있습니다}

얕은 사본 :단순히 A에 대한 참조 사본을 B로 만듭니다. A의 주소 사본으로 생각하십시오. 따라서 A와 B의 주소는 동일한 메모리 위치, 즉 데이터 내용을 가리키는 것과 동일합니다.

딥 카피 :단순히 A의 모든 멤버의 사본을 만들고, B에 대해 다른 위치에 메모리를 할당 한 다음 복사 된 멤버를 B에 할당하여 깊은 사본을 달성합니다. 이런 식으로, A가 존재하지 않는 경우 B가 여전히 메모리에서 유효합니다. 사용하기에 적합한 용어는 복제이며, 여기서 둘 다 완전히 동일하지만 다르지만 (예 : 메모리 공간에서 두 개의 다른 엔티티로 저장) 또한 딥 카피 중에 선택할 속성을 포함/제외 목록을 통해 결정할 수있는 클론 래퍼를 제공 할 수도 있습니다. API를 만들 때 이것은 매우 일반적인 관행입니다.

얕은 사본을 선택할 수 있습니다 만 _if 당신은 관련된 지분을 이해합니다. C ++ 또는 C에서 다루는 거대한 포인터가있는 경우 얕은 객체 사본을 수행하는 것은 다음과 같습니다. 진짜 나쁜 생각.

example_of_deep copy_ 예를 들어, 이미지 처리 및 객체 인식을 수행하려고 할 때는 처리 영역에서 "무의미하고 반복적 인 움직임"을 마스킹해야합니다. 이미지 포인터를 사용하는 경우 마스크 이미지를 저장하는 사양이있을 수 있습니다. 이제 ... 이미지의 얕은 사본을 수행하면 스택에서 포인터 참조가 사망하면 참조를 잃어 버렸고 해당 사본은 어느 시점에서 액세스 위반의 런타임 오류가 발생합니다. 이 경우 필요한 것은 클로닝하여 이미지의 깊은 사본입니다. 이런 식으로 마스크를 미래에 필요한 경우 마스크를 검색 할 수 있습니다.

example_of_shally_copy StackoverFlow의 사용자에 비해 지식이 풍부하지 않으므로이 부분을 자유롭게 삭제하고 명확히 할 수 있다면 좋은 예제를 작성하십시오. 그러나 나는 당신의 프로그램이 무한한 시간 동안 실행될 것이라는 것을 알고 있다면 얕은 사본을하는 것은 좋은 생각이 아니라고 생각합니다. 아마추어 또는 초보자에게 무언가를 보여주고 있다면 (예 : C/C ++ 자습서) 아마 괜찮을 것입니다. 그러나 감시 및 탐지 시스템 또는 Sonar 추적 시스템과 같은 애플리케이션을 실행중인 경우 프로그램이 조만간 얕은 복사를 계속하지 않아야합니다.

char * Source = "Hello, world.";

char * ShallowCopy = Source;    

char * DeepCopy = new char(strlen(Source)+1);
strcpy(DeepCopy,Source);        

'Shallowcopy'는 'Source'와 같은 메모리의 동일한 위치를 가리 킵니다. 'DeepCopy'는 메모리의 다른 위치를 가리 키지 만 내용은 동일합니다.

얕은 사본은 무엇입니까?

얕은 사본은 객체의 약간 현저한 사본입니다. 원래 객체에 값의 정확한 사본이있는 새 개체가 생성됩니다. 객체의 필드 중 하나가 다른 객체에 대한 참조 인 경우, 참조 주소 만 복사되며 메모리 주소 만 복사됩니다. Shallow Copy

이 그림에서 MainObject1 필드가 있습니다 field1 유형 int 및 ContainObject1 유형의 ContainObject. 얕은 사본을 할 때 MainObject1, MainObject2 함께 만들어졌습니다 field2 복사 값을 포함합니다 field1 그리고 여전히 가리키고 있습니다 ContainObject1 그 자체. 그 이후로 주목하십시오 field1 원시 유형이며 그 값은 다음으로 복사됩니다. field2 하지만 그때부터 ContainedObject1 대상, MainObject2 여전히 지적합니다 ContainObject1. 따라서 변경 사항이 변경됩니다 ContainObject1 안에 MainObject1 반영됩니다 MainObject2.

이제 이것이 얕은 사본이라면 딥 카피가 무엇인지 봅시다.

딥 카피 란 무엇입니까?

딥 카피는 모든 필드를 복사하고 필드가 지적한 동적으로 할당 된 메모리의 사본을 만듭니다. 딥 카피는 객체를 참조하는 객체와 함께 복사 할 때 발생합니다.Deep Copy

이 그림에서 MainObject1에는 필드가 있습니다 field1 유형 int 및 ContainObject1 유형의 ContainObject. 당신이 깊은 사본을 할 때 MainObject1, MainObject2 함께 만들어졌습니다 field2 복사 값을 포함합니다 field1 그리고 ContainObject2 복사 값을 포함합니다 ContainObject1. 변경 사항에 유의하십시오 ContainObject1 안에 MainObject1 반영되지 않습니다 MainObject2.

좋은 기사

객체 지향 프로그래밍에서 유형에는 멤버 필드 모음이 포함되어 있습니다. 이 필드는 값 또는 기준 (즉, 값에 대한 포인터)에 의해 저장 될 수 있습니다.

얕은 사본에서 유형의 새 인스턴스가 생성되고 값이 새 인스턴스에 복사됩니다. 참조 포인터는 값과 마찬가지로 복사됩니다. 따라서 참조는 원래 객체를 가리키고 있습니다. 참조로 저장된 멤버에 대한 변경 사항은 원본과 사본 모두에 나타납니다. 참조 된 객체에 대한 사본이 없었기 때문입니다.

딥 카피에서 값에 의해 저장된 필드는 이전과 같이 복사되지만 참조로 저장된 개체에 대한 포인터는 복사되지 않습니다. 대신, 참조 된 객체로 딥 카피가 만들어지고 새 개체에 대한 포인터가 저장됩니다. 참조 된 객체에 대한 변경 사항은 객체의 다른 사본에 영향을 미치지 않습니다.

'Shallowcopy'는 'Source'와 같은 메모리의 동일한 위치를 가리 킵니다. 'DeepCopy'는 메모리의 다른 위치를 가리 키지 만 내용은 동일합니다.

var source = { firstName="Jane", lastname="Jones" };
var shallow = ShallowCopyOf(source);
var deep = DeepCopyOf(source);
source.lastName = "Smith";
WriteLine(source.lastName); // prints Smith
WriteLine(shallow.lastName); // prints Smith
WriteLine(deep.lastName); // prints Jones

얕은 복제 :
정의 : "객체의 얕은 사본은 '기본'객체를 복사하지만 내부 객체를 복사하지 않습니다." 사용자 정의 객체 (예 : Employee)가 원시적, 문자열 유형 변수 만 있으면 얕은 복제를 사용합니다.

Employee e = new Employee(2, "john cena");
Employee e2=e.clone();

당신은 돌아옵니다 super.clone(); 재정의 클론 () 메소드에서 작업이 끝났습니다.

깊은 복제:
정의 : "얕은 사본과 달리 딥 카피는 완전히 독립적 인 사본입니다."
직원 객체에 다른 사용자 정의 객체를 보유하는 경우를 의미합니다.

Employee e = new Employee(2, "john cena", new Address(12, "West Newbury", "Massachusetts");

그런 다음 '주소'객체를 복제하려면 코드를 작성해야합니다. 그렇지 않으면 주소 객체가 복제되지 않으며 복제 된 직원 객체에서 주소 값을 변경할 때 버그가 발생합니다.

딥 카피

딥 카피는 모든 필드를 복사하고 필드가 지적한 동적으로 할당 된 메모리의 사본을 만듭니다. 딥 카피는 객체를 참조하는 객체와 함께 복사 할 때 발생합니다.

얕은 사본

얕은 사본은 객체의 약간 현저한 사본입니다. 원래 객체에 값의 정확한 사본이있는 새 개체가 생성됩니다. 객체의 필드 중 하나가 다른 객체에 대한 참조 인 경우, 참조 주소 만 복사되며 메모리 주소 만 복사됩니다.

얕은 사본- 원본 및 얕은 카피 객체 내부의 참조 변수는 다음을 참조합니다. 흔한 물체.

딥 카피- 원본 및 심도있는 개체 내부의 참조 변수는 다음을 참조합니다. 다른 물체.

클론은 항상 얕은 사본을합니다.

public class Language implements Cloneable{

    String name;
    public Language(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

메인 클래스는 다음과 같습니다.

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("JAVA"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);

      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true

      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false

} 

위의 출력은

거짓된 진실

허위 거짓

Origional Object에서 만들어진 모든 변경은 깊은 물체가 아닌 얕은 물체에 반영됩니다.

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

산출- 비주얼베이스 c

공식적인 정의보다는 예를 제시하고 싶습니다.

var originalObject = { 
    a : 1, 
    b : 2, 
    c : 3,
};

이 코드는 a를 보여줍니다 얕은 사본:

var copyObject1 = originalObject;

console.log(copyObject1.a);         // it will print 1 
console.log(originalObject.a);       // it will also print 1 
copyObject1.a = 4; 
console.log(copyObject1.a);           //now it will print 4 
console.log(originalObject.a);       // now it will also print 4

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // now it will print 1

이 코드는 a를 보여줍니다 딥 카피:

var copyObject2 = Object.assign({}, originalObject);

console.log(copyObject2.a);        // it will print 1 
console.log(originalObject.a);      // it will also print 1 
copyObject2.a = 4; 
console.log(copyObject2.a);        // now it will print 4 
console.log(originalObject.a);      // !! now it will print 1 !!
struct sample
{
    char * ptr;
}
void shallowcpy(sample & dest, sample & src)
{
    dest.ptr=src.ptr;
}
void deepcpy(sample & dest, sample & src)
{
    dest.ptr=malloc(strlen(src.ptr)+1);
    memcpy(dest.ptr,src.ptr);
}

간단히 말하면 얕은 사본은 참조로 호출과 유사하며 딥 카피는 값으로 호출하는 것과 유사합니다.

참조 별 호출에서 함수의 공식 및 실제 매개 변수는 동일한 메모리 위치 및 값을 나타냅니다.

값에 따라 호출에서, 함수의 공식적인 매개 변수는 모두 다른 메모리 위치를 의미하지만 동일한 값을 갖는다.

ARR1과 ARR2라는 두 개의 배열이 있다고 상상해보십시오.

arr1 = arr2;   //shallow copy
arr1 = arr2.clone(); //deep copy

얕은 복사는 새 개체를 생성 한 다음 현재 객체의 비 정적 필드를 새 개체에 복사합니다. 필드가 값 유형 인 경우-> 필드의 비트 바이트 사본이 수행됩니다. a 참조 유형 -> 참조가 복사되었지만 참조 된 객체는 그렇지 않습니다. 따라서 원래 객체와 클론은 동일한 객체를 나타냅니다.

깊은 사본은 새 객체를 생성 한 다음 현재 객체의 비 종종 필드를 새 개체에 복사합니다. 필드가 a 가치 유형 -> 필드의 비트 바이트 사본이 수행됩니다. 필드가 a 참조 유형 -> 참조 객체의 새 사본이 수행됩니다. 클로닝 될 클래스는 [시리얼 화 가능]로 표시되어야합니다.

[블로그]에서 발췌: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

딥 카피 한 개체의 내용을 사용하여 동일한 클래스의 다른 인스턴스를 만드는 작업이 포함됩니다.깊은 복사에서는 두 개체에 동일한 정보가 포함될 수 있지만 대상 개체에는 자체 버퍼와 리소스가 있습니다.두 개체 중 하나가 파괴되더라도 나머지 개체에는 영향을 미치지 않습니다.오버로드된 할당 연산자는 개체의 전체 복사본을 생성합니다.

얕은 사본 한 개체의 내용을 동일한 클래스의 다른 인스턴스에 복사하여 미러 이미지를 만드는 작업이 포함됩니다.참조 및 포인터의 직접 복사로 인해 두 개체는 예측할 수 없도록 다른 개체의 외부에 포함된 동일한 내용을 공유합니다.

설명:

복사 생성자를 사용하여 간단히 멤버별로 데이터 값을 복사합니다.이 복사 방법을 얕은 복사라고 합니다.객체가 기본 제공 유형으로 구성되고 포인터가 없는 간단한 클래스인 경우 이는 허용될 수 있습니다.이 함수는 값과 객체를 사용하며 해당 동작은 얕은 복사본으로 변경되지 않으며 멤버인 포인터의 주소만 복사되고 주소가 가리키는 값은 복사되지 않습니다.그러면 객체의 데이터 값이 함수에 의해 실수로 변경됩니다.함수가 범위를 벗어나면 모든 데이터가 포함된 객체의 복사본이 스택에서 팝됩니다.

객체에 포인터가 있으면 전체 복사를 실행해야 합니다.객체의 전체 복사를 사용하면 자유 저장소의 객체에 메모리가 할당되고 가리키는 요소가 복사됩니다.함수에서 반환되는 개체에는 전체 복사본이 사용됩니다.

다른 답변에 더 많은 것을 추가하려면

  • 객체의 얕은 사본은 값 유형 기반 속성에 대한 값별로 사본을 수행하고 참조 유형 기반 속성에 대해 참조별로 복사합니다.
  • 객체의 딥 카피는 값 유형 기반 속성에 대한 값별로 사본을 수행하고 참조 유형 기반 속성에 대한 값별로 복사하여 계층 구조 (참조 유형)의 깊이

얕은 사본은 새로운 화합물 객체를 구성하고 그 참조를 원래 객체에 삽입합니다.

얕은 사본과 달리 DeepCopy는 새로운 화합물 물체를 구성하고 원래 화합물 물체의 원래 물체의 사본을 삽입합니다.

예를 들어 보겠습니다.

import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)

위의 코드는 거짓을 인쇄합니다.

방법을 보자.

원래 복합 물체 x=[1,[2]] (내부 객체 (Inception)가 있기 때문에 화합물이라고합니다.

enter image description here

이미지에서 볼 수 있듯이 내부 목록이 있습니다.

그런 다음 우리는 그것을 사용하여 얕은 사본을 만듭니다 y = copy.copy(x). Python이 여기서하는 일은 새로운 화합물 객체를 만들 것이지만 그 안에있는 물체는 Orignal 객체를 가리키고 있습니다.

enter image description here

이미지에서 그것은 외부 목록에 대한 새 사본을 만들었습니다. 그러나 내부 목록은 원래 목록과 동일하게 유지됩니다.

이제 우리는 그것을 사용하여 딥 코피를 만듭니다 z = copy.deepcopy(x). Python이 여기서하는 것은 외부 목록과 내부 목록에 대한 새로운 객체를 만들 것입니다. 아래 이미지에 표시된대로 (빨간색으로 강조 표시됨).

enter image description here

최종 코드에서 인쇄 False, y와 z는 동일한 객체가 아니기 때문에.

HTH.

얕은 사본은 새로운 참조를 만들지 않지만 딥 카피는 새로운 참조를 생성합니다.

다음은 깊고 얕은 사본을 설명하는 프로그램입니다.

public class DeepAndShollowCopy {
    int id;
    String name;
    List<String> testlist = new ArrayList<>();

    /*
    // To performing Shallow Copy 
    // Note: Here we are not creating any references. 
      public DeepAndShollowCopy(int id, String name, List<String>testlist)
       { 

       System.out.println("Shallow Copy for Object initialization");
       this.id = id; 
       this.name = name; 
       this.testlist = testlist; 

       }
    */  

    // To performing Deep Copy 
    // Note: Here we are creating one references( Al arraylist object ). 
    public DeepAndShollowCopy(int id, String name, List<String> testlist) {
        System.out.println("Deep Copy for Object initialization");
        this.id = id;
        this.name = name;
        String item;
        List<String> Al = new ArrayList<>();
        Iterator<String> itr = testlist.iterator();
        while (itr.hasNext()) {
            item = itr.next();
            Al.add(item);
        }
        this.testlist = Al;
    }


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Oracle");
        list.add("C++");
        DeepAndShollowCopy copy=new DeepAndShollowCopy(10,"Testing", list);
        System.out.println(copy.toString());
    }
    @Override
    public String toString() {
        return "DeepAndShollowCopy [id=" + id + ", name=" + name + ", testlist=" + testlist + "]";
    }
}

Ararys 복사 :

배열은 클래스이므로 참조 유형이므로 Array1 = array2는 동일한 배열을 참조하는 두 개의 변수를 초래합니다.

그러나이 예를 살펴보십시오.

  static void Main()
    {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; 
        int[] arr2 = new int[] { 6, 7, 8, 9, 0 };

        Console.WriteLine(arr1[2] + " " + arr2[2]);
        arr2 = arr1;
        Console.WriteLine(arr1[2] + " " + arr2[2]); 
        arr2 = (int[])arr1.Clone();
        arr1[2] = 12;
        Console.WriteLine(arr1[2] + " " + arr2[2]);
    }

얕은 클론 복제 된 배열로 표시되는 메모리 만 복사 함을 의미합니다.

배열에 값 유형 객체가 포함 된 경우 값이 복사됩니다.;

배열에 참조 유형이 포함 된 경우 참조 만 복사됩니다. 결과적으로 멤버가 동일한 개체를 참조하는 두 개의 배열이 있습니다..

참조 유형이 복제되는 딥 카피를 만들려면 배열을 통해 반복하고 각 요소를 수동으로 복제해야합니다.

위의 모든 정의를 추가하면 가장 일반적으로 사용되는 딥 카피는 클래스의 사본 생성자 (또는 과부하 할당 오프레이터)에 있습니다.

얕은 사본 ->는 사본 생성자를 제공하지 않을 때입니다. 여기서는 객체 만 복사되지만 클래스의 모든 멤버가 복사되지는 않습니다.

딥 카피 ->은 수업에서 사본 생성자 또는 과부하 할당을 구현하기로 결정했으며 클래스의 모든 멤버를 복사 할 수 있습니다.

MyClass& MyClass(const MyClass& obj) // copy constructor for MyClass
{
          // write your code, to copy all the members and return the new object
}
MyClass& operator=(const MyClass& obj) // overloading assignment operator,
{
          // write your code, to copy all the members and return the new object
}

사본 생성자는 이전에 생성 된 동일한 클래스의 개체로 새 개체를 초기화하는 데 사용됩니다. 기본적으로 컴파일러는 얕은 사본을 썼습니다. 동적 메모리 할당이 관련 될 때 동적 메모리 할당이 관련되지 않으면 얕은 사본이 잘 작동합니다. 두 객체 모두 힙의 동일한 메모리 위치를 가리키 므로이 문제를 제거하기 위해 두 객체에 자체 속성 사본이 있도록 딥 사본을 썼습니다. 기억 속에. 완전한 예와 설명이있는 세부 사항을 읽으려면 기사를 볼 수 있습니다. C ++ 생성자.

얕은 복사 간의 혼동을 위해 조금 더 추가하고 단순히 목록에 새 변수 이름을 할당합니다.

"우리가 가지고 있다고 가정 해 봅시다 :

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

이 문은 3개의 목록을 생성합니다.내부 목록 2개와 외부 목록 1개.그러면 외부 목록에 대한 참조가 x라는 이름으로 사용 가능해집니다.만약 우리가 그렇게 한다면

y = x

데이터가 복사되지 않습니다.우리는 여전히 메모리 어딘가에 동일한 3개의 목록을 가지고 있습니다.이 모든 작업은 이전 이름인 x 외에 y라는 이름으로 외부 목록을 사용할 수 있게 만든 것입니다.만약 우리가 그렇게 한다면

y = list(x)

또는

y = x[:]

그러면 x와 동일한 내용을 가진 새 목록이 생성됩니다.목록 x에는 2개의 내부 목록에 대한 참조가 포함되어 있으므로 새 목록에도 동일한 2개의 내부 목록에 대한 참조가 포함됩니다.하나의 목록(외부 목록)만 복사됩니다.이제 메모리에는 4개의 목록이 있습니다. 두 개의 내부 목록, 외부 목록, 외부 목록의 복사본입니다.원래 외부 목록은 x라는 이름으로 사용할 수 있고 새 외부 목록은 y라는 이름으로 사용할 수 있습니다.

내부 목록은 복사되지 않았습니다!이 시점에서 x 또는 y에서 내부 목록에 액세스하고 편집할 수 있습니다!

2차원(또는 그 이상) 목록 또는 모든 종류의 중첩 데이터 구조가 있고 모든 항목의 전체 복사본을 만들고 싶다면 복사 모듈에서 deepcopy() 함수를 사용하는 것이 좋습니다.귀하의 솔루션은 외부 목록의 항목을 반복하고 각 항목의 복사본을 만든 다음 모든 내부 복사본에 대해 새로운 외부 목록을 작성하므로 2D 목록에서도 작동합니다.

원천: https://www.reddit.com/r/learnpython/comments/1afldr/why_is_copying_a_list_so_damn_difficult_in_python/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top