파이썬

[python] Python의 목록 메서드 추가와 확장의 차이점은 무엇입니까?

zooheon 2022. 8. 22. 22:55
반응형

append()목록 방법 과 의 차이점은 무엇입니까 extend()?

 

append목록 끝에 지정된 객체를 추가합니다.

>>> x = [1, 2, 3]
>>> x.append([4, 5])
>>> print(x)
[1, 2, 3, [4, 5]]

extend지정된 iterable에서 요소를 추가하여 목록을 확장합니다.

>>> x = [1, 2, 3]
>>> x.extend([4, 5])
>>> print(x)
[1, 2, 3, 4, 5]

 

append목록에 요소를 추가합니다. extend첫 번째 목록을 다른 목록/반복 가능 항목과 연결합니다.

>>> xs = ['A', 'B']
>>> xs
['A', 'B']

>>> xs.append("D")
>>> xs
['A', 'B', 'D']

>>> xs.append(["E", "F"])
>>> xs
['A', 'B', 'D', ['E', 'F']]

>>> xs.insert(2, "C")
>>> xs
['A', 'B', 'C', 'D', ['E', 'F']]

>>> xs.extend(["G", "H"])
>>> xs
['A', 'B', 'C', 'D', ['E', 'F'], 'G', 'H']

 

목록 메서드 추가와 확장의 차이점은 무엇입니까?

  • append목록의 끝에 단일 요소로 인수를 추가합니다. 목록 자체의 길이가 1씩 늘어납니다.
  • extend인수를 반복하여 목록에 각 요소를 추가하여 목록을 확장합니다. 목록의 길이는 iterable 인수에 있는 요소의 수만큼 증가합니다.

append

list.append메서드는 목록 끝에 개체를 추가합니다.

my_list.append(object) 

개체가 무엇이든, 숫자, 문자열, 다른 목록 또는 다른 무엇이든 목록 my_list의 단일 항목으로 끝에 추가됩니다.

>>> my_list
['foo', 'bar']
>>> my_list.append('baz')
>>> my_list
['foo', 'bar', 'baz']

따라서 목록은 객체임을 명심하십시오. 목록에 다른 목록을 추가하는 경우 첫 번째 목록은 목록 끝에 있는 단일 개체가 됩니다(원하는 것이 아닐 수도 있음).

>>> another_list = [1, 2, 3]
>>> my_list.append(another_list)
>>> my_list
['foo', 'bar', 'baz', [1, 2, 3]]
                     #^^^^^^^^^--- single item at the end of the list.

extend

list.extend메서드는 iterable에서 요소를 추가하여 목록을 확장합니다.

my_list.extend(iterable)

따라서 확장을 사용하면 iterable의 각 요소가 목록에 추가됩니다. 예를 들어:

>>> my_list
['foo', 'bar']
>>> another_list = [1, 2, 3]
>>> my_list.extend(another_list)
>>> my_list
['foo', 'bar', 1, 2, 3]

문자열은 반복 가능하므로 목록을 문자열로 확장하는 경우 문자열을 반복할 때 각 문자를 추가해야 합니다(원하는 것이 아닐 수 있음).

>>> my_list.extend('baz')
>>> my_list
['foo', 'bar', 1, 2, 3, 'b', 'a', 'z']

연산자 과부하, __add__( +) 및 __iadd__( +=)

++=연산자는 모두 에 대해 정의됩니다 list. 그들은 확장과 의미상 유사합니다.

my_list + another_list메모리에 세 번째 목록을 생성하므로 결과를 반환할 수 있지만 두 번째 iterable은 목록이어야 합니다.

my_list += another_list새 목록을 생성하지 않도록 목록을 제자리에서 수정합니다(내부 연산자이고 목록은 변경 가능한 객체입니다 ) . 또한 두 번째 iterable은 모든 종류의 iterable이 될 수 있다는 점에서 확장과 같이 작동합니다.

혼동하지 마십시오 - my_list = my_list + another_list와 동일 하지 않음 +=- my_list에 할당된 완전히 새로운 목록을 제공합니다.

시간 복잡도

추가는 ( 상각된 ) 일정한 시간 복잡도 , O(1)을 가집니다.

확장은 시간 복잡도 O(k)를 가집니다.

여러 호출을 반복 append하여 복잡성을 추가하여 확장과 동일하게 만들고 확장의 반복이 C로 구현되기 때문에 반복 가능한 항목에서 목록에 연속적인 항목을 추가하려는 경우 항상 더 빠릅니다.

"상각"에 대해 - 목록 개체 구현 소스 에서 :

    /* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().

이것은 우리가 필요한 것보다 더 큰 메모리 재할당의 이점을 미리 얻을 수 있음을 의미하지만 더 큰 것으로 다음 한계 재할당에서 비용을 지불할 수 있습니다. 모든 추가에 대한 총 시간은 O(n)에서 선형이며 추가당 할당된 시간은 O(1)이 됩니다.

성능

추가를 사용하여 확장과 동일한 결과를 얻을 수 있으므로 무엇이 더 성능이 좋은지 궁금할 수 있습니다. 다음 기능은 동일한 작업을 수행합니다.

def append(alist, iterable):
    for item in iterable:
        alist.append(item)
        
def extend(alist, iterable):
    alist.extend(iterable)

시간을 정합시다.

import timeit

>>> min(timeit.repeat(lambda: append([], "abcdefghijklmnopqrstuvwxyz")))
2.867846965789795
>>> min(timeit.repeat(lambda: extend([], "abcdefghijklmnopqrstuvwxyz")))
0.8060121536254883

타이밍에 대한 의견 다루기

한 댓글 작성자는 다음과 같이 말했습니다.

완벽한 대답, 한 요소만 추가해서 비교하는 타이밍이 그리워

의미상 올바른 일을 하십시오. iterable의 모든 요소를 ​​추가하려면 extend. 하나의 요소만 추가하는 경우 append.

자, 제 시간에 이것이 어떻게 작동하는지 알아보기 위해 실험을 만들어 보겠습니다.

def append_one(a_list, element):
    a_list.append(element)

def extend_one(a_list, element):
    """creating a new list is semantically the most direct
    way to create an iterable to give to extend"""
    a_list.extend([element])

import timeit

그리고 단지 확장을 사용하기 위해 이터러블을 만드는 것이 (사소한) 시간 낭비라는 것을 알았습니다.

>>> min(timeit.repeat(lambda: append_one([], 0)))
0.2082819009956438
>>> min(timeit.repeat(lambda: extend_one([], 0)))
0.2397019260097295

우리는 추가할 요소 가 하나만extend 있을 때 사용하여 얻을 수 있는 것이 없음을 이것으로부터 배웁니다 .

또한 이러한 타이밍은 그다지 중요하지 않습니다. 나는 단지 파이썬에서 의미론적으로 올바른 일을 하는 것이 옳은 일을 하는 것이라는 요점을 알려주기 위해 그들에게 보여주고 있는 것 입니다 .

두 개의 비교 가능한 작업에서 타이밍을 테스트하고 모호하거나 반대의 결과를 얻을 수 있습니다. 의미상 올바른 일을 하는 데만 집중하세요.

결론

iterable의 각 요소 를 목록에 추가하려는 경우 의미상 더 명확하고 , extend보다 훨씬 빠르게 실행할 수 있습니다 .append

목록에 추가할 단일 요소(이터러블이 아님)만 있는 경우 append.

 

반응형