IT

어떻게 하면 짧은 비단뱀 목록을 추가할 수 있나요?

itgroup 2022. 10. 28. 20:41
반응형

어떻게 하면 짧은 비단뱀 목록을 추가할 수 있나요?

list.append()는 목록의 끝에 추가됩니다.이것은 을 설명한다.list.prepend()는 대규모 리스트의 퍼포먼스 문제로 인해 존재하지 않습니다.간단한 리스트의 경우 값을 부가하려면 어떻게 해야 합니까?

s.insert(0, x)형식이 가장 일반적입니다.

다만, 리스트 대신에 collections.deque 를 사용하는 것을 검토해 주세요.디큐에 대한 프리펜딩은 일정한 시간에 실행됩니다.목록에 대한 추가는 선형 시간으로 실행됩니다.

그러면 다음과 같은 새 목록이 생성됩니다.x기존 목록을 변경하지 않고 선두에 추가합니다.

new_list = [x] + old_list

짧은 비단뱀 목록 앞에 붙이는 관용 구문은 무엇입니까?

당신은 보통 Python의 목록에 반복적으로 추가하기를 원하지 않는다.

리스트가 짧아서 많이 안 하면...그럼 됐어

list.insert

list.insert이렇게 사용할 수 있습니다.

list.insert(0, x)

하지만 이것은 비효율적입니다. 왜냐하면 Python에서는list는 포인터의 배열입니다.Python은 리스트 내의 모든 포인터를 1개씩 아래로 이동시켜 첫 번째 슬롯에 오브젝트에 포인터를 삽입해야 합니다.따라서 이것은 당신이 요구하는 바와 같이 비교적 짧은 리스트에 대해서만 유효합니다.

이것이 실장되어 있는 CPython 소스의 일부를 다음에 나타냅니다.여기서 보시는 것처럼 어레이의 끝에서 시작하여 삽입할 때마다 모든 것을 1개씩 아래로 이동합니다.

for (i = n; --i >= where; )
    items[i+1] = items[i];

요소를 효율적으로 추가할 수 있는 컨테이너/목록을 원하는 경우 링크된 목록이 필요합니다.Python은 이중으로 연결된 목록을 가지고 있으며, 시작과 종료에 빠르게 삽입할 수 있습니다.deque.

deque.appendleft

A collections.deque에는 목록의 많은 메서드가 있습니다. list.sort예외입니다.deque완전히 리스코프를 대체할 수 있는 것은 결코 아니다list.

>>> set(dir(list)) - set(dir(deque))
{'sort'}

deque또,appendleft방법(및popleft).deque는 더블 엔드 큐와 더블 링크 리스트입니다.길이에 관계없이 항상 같은 시간이 걸리고 있습니다.빅 O 표기법에서는 O(1)와 리스트의 O(n) 시간.사용방법은 다음과 같습니다.

>>> import collections
>>> d = collections.deque('1234')
>>> d
deque(['1', '2', '3', '4'])
>>> d.appendleft('0')
>>> d
deque(['0', '1', '2', '3', '4'])

deque.extendleft

또한 데크(deque)도 관련이 있습니다.extendleftmethod를 반복합니다.

>>> from collections import deque
>>> d2 = deque('def')
>>> d2.extendleft('cba')
>>> d2
deque(['a', 'b', 'c', 'd', 'e', 'f'])

각 요소는 한 번에 하나씩 선두에 추가되므로 실질적으로 순서가 반전됩니다.

퍼포먼스listdeque

먼저 몇 가지 반복적인 프리펜딩으로 설정합니다.

import timeit
from collections import deque


def list_insert_0(prepends: int):
    l = []
    for i in range(prepends):
        l.insert(0, i)

def list_slice_insert(prepends):
    l = []
    for i in range(prepends):
        l[:0] = [i]      # semantically same as list.insert(0, i)

def list_add(prepends):
    l = []
    for i in range(prepends):
        l = [i] + l      # caveat: new list each time

def deque_appendleft(prepends):
    d = deque()
    for i in range(prepends):
        d.appendleft(i)  # semantically same as list.insert(0, i)

def deque_extendleft(prepends):
    d = deque()
    d.extendleft(range(prepends)) # semantically same as deque_appendleft above

또한 다양한 용도에 걸쳐 모든 작업을 공정하게 비교할 수 있는 분석 기능도 있습니다.

def compare_prepends(n, runs_per_trial):
    results = {}
    for function in (
        list_insert_0, list_slice_insert,
        list_add, deque_appendleft, deque_extendleft,
        ):
        shortest_time = min(timeit.repeat(
            lambda: function(n), number=runs_per_trial))
        results[function.__name__] = shortest_time
    ranked_methods = sorted(results.items(), key=lambda kv: kv[1])
    for name, duration in ranked_methods:
        print(f'{name} took {duration} seconds')

하기 위해 )repeat3번입니다.

compare_prepends(20, 1_000_000)
compare_prepends(100, 100_000)
compare_prepends(500, 100_000)
compare_prepends(2500, 10_000)
>>> compare_prepends(20, 1_000_000)
deque_extendleft took 0.6490256823599339 seconds
deque_appendleft took 1.4702797569334507 seconds
list_insert_0 took 1.9417422469705343 seconds
list_add took 2.7092894352972507 seconds
list_slice_insert took 3.1809083241969347 seconds
>>> compare_prepends(100, 100_000)
deque_extendleft took 0.1177942156791687 seconds
deque_appendleft took 0.5385235995054245 seconds
list_insert_0 took 0.9471780974417925 seconds
list_slice_insert took 1.4850486349314451 seconds
list_add took 2.1660344172269106 seconds
>>> compare_prepends(500, 100_000)
deque_extendleft took 0.7309095915406942 seconds
deque_appendleft took 2.895373275503516 seconds
list_slice_insert took 8.782583676278591 seconds
list_insert_0 took 8.931685039773583 seconds
list_add took 30.113558700308204 seconds
>>> compare_prepends(2500, 10_000)
deque_extendleft took 0.4839253816753626 seconds
deque_appendleft took 1.5615574326366186 seconds
list_slice_insert took 6.712615916505456 seconds
list_insert_0 took 13.894083382561803 seconds
list_add took 72.1727528590709 seconds

데크가 훨씬 빠릅니다.목록이 길어질수록 디크는 더 잘 작동합니다. deque's deque's를 할 수 extendleft최고의 퍼포먼스를 얻을 수 있을 것 같아요.

할 필요가 는, 작은는, 「」라고 하는 .list.insert는 더 빨리 동작하지만 목록이 클수록 슬라이스 표기법을 사용한 삽입이 더 빨라집니다.

목록 앞에 추가 안 함

리스트는 추가되는 것이지 선두에 추가되는 것이 아닙니다.이러한 종류의 프리펜딩이 코드의 퍼포먼스를 해치는 경우는, 디큐로 전환하거나, 시멘틱스를 반대로 해 같은 목적을 달성할 수 있는 경우는, 리스트를 리버스 해 대신에 추가해 주세요.

된 Python의 에 Python을 .list★★★★★★ 。

나처럼 이 질문을 발견한 사람이 있다면 제안된 방법에 대한 성능 테스트를 다음에 제시하겠습니다.

Python 2.7.8

In [1]: %timeit ([1]*1000000).insert(0, 0)
100 loops, best of 3: 4.62 ms per loop

In [2]: %timeit ([1]*1000000)[0:0] = [0]
100 loops, best of 3: 4.55 ms per loop

In [3]: %timeit [0] + [1]*1000000
100 loops, best of 3: 8.04 ms per loop

바와 같이, '우리'는 '우리'입니다.insert슬라이스 할당은 명시적 추가보다 거의 두 배 빠르고 결과에 매우 근접합니다.Raymond Hettinger가 지적했듯이insert을 사용하다저는 개인적으로 목록보다 이 방법을 더 선호합니다.

내 생각에, Python에서 요소나 목록을 다른 목록에 추가하는 가장 우아하고 관용적인 방법은 확장 연산자 *(패킹 해제 연산자라고도 함)를 사용하는 것이다.

# Initial list
l = [4, 5, 6]

# Modification
l = [1, 2, 3, *l]

수정 후의 리스트는 다음과 같습니다.[1, 2, 3, 4, 5, 6]

또, 그림과 같이, 2개의 리스트를 연산자+와 간단하게 조합하는 것도 좋아합니다.

# Prepends [1, 2, 3] to l
l = [1, 2, 3] + l

# Prepends element 42 to l
l = [42] + l

접근법은l.insert(0, value)더군다나, 더군다나insert()는 단일 요소만 프리펜딩할 수 있지만 위의 접근법은 단일 요소 또는 여러 요소를 프리펜딩하는 구문과 동일합니다.

4가지 방법에 대해 설명하겠습니다.

  1. insert() 사용
>>> 
>>> l = list(range(5))
>>> l
[0, 1, 2, 3, 4]
>>> l.insert(0, 5)
>>> l
[5, 0, 1, 2, 3, 4]
>>> 
  1. [] 및 + 사용
>>> 
>>> l = list(range(5))
>>> l
[0, 1, 2, 3, 4]
>>> l = [5] + l
>>> l
[5, 0, 1, 2, 3, 4]
>>> 
  1. 슬라이싱 사용
>>> 
>>> l = list(range(5))
>>> l
[0, 1, 2, 3, 4]
>>> l[:0] = [5]
>>> l
[5, 0, 1, 2, 3, 4]
>>> 
  1. collections.deque.appendleft() 사용
>>> 
>>> from collections import deque
>>> 
>>> l = list(range(5))
>>> l
[0, 1, 2, 3, 4]
>>> l = deque(l)
>>> l.appendleft(5)
>>> l = list(l)
>>> l
[5, 0, 1, 2, 3, 4]
>>> 

python > = 3.0으로 빠르게 작업을 진행했을 것입니다.

list=[0,*list]

가장 효율적인 방법은 아닐지 모르지만, 내 생각에는 가장 피톤적인 방법인 것 같아요.

언급URL : https://stackoverflow.com/questions/8537916/how-do-i-prepend-to-a-short-python-list

반응형