[python] Python : n 개의 목록을 만드는 가장 빠른 방법

그래서 빈 목록 목록을 가장 잘 만드는 방법이 궁금합니다.

[[],[],[]...]

파이썬이 메모리의 목록과 함께 작동하는 방식 때문에 작동하지 않습니다.

[[]]*n

이것은 생성 [[],[],...]되지만 각 요소는 동일한 목록입니다.

d = [[]]*n
d[0].append(1)
#[[1],[1],...]

목록 이해와 같은 것이 작동합니다.

d = [[] for x in xrange(0,n)]

그러나 이것은 루핑을 위해 Python VM을 사용합니다. 묵시적 루프를 사용하는 방법이 있습니까 (C로 작성된 이점을 활용)?

d = []
map(lambda n: d.append([]),xrange(0,10))

이것은 실제로 더 느립니다. 🙁



답변

아마 조금 더 빠른 유일한 방법은

d = [[] for x in xrange(n)]

이다

from itertools import repeat
d = [[] for i in repeat(None, n)]

int모든 반복에서 새 객체 를 만들 필요가 없으며 내 컴퓨터에서 약 15 % 더 빠릅니다.

편집 : NumPy를 사용하면 다음을 사용하여 Python 루프를 피할 수 있습니다.

d = numpy.empty((n, 0)).tolist()

그러나 이것은 실제로 목록 이해보다 2.5 배 느립니다.


답변

목록 내포는 실제로 명시 적 루프 ( 예 : 함수 dis출력 참조)보다 더 효율적으로 구현 되며, map방법은 매 반복마다 ophaque 호출 가능 객체를 호출해야하므로 상당한 오버 헤드가 발생합니다.

그럼에도 불구하고 [[] for _dummy in xrange(n)]그것을 수행하는 올바른 방법이며 다양한 다른 방법 간의 작은 속도 차이 중요하지 않습니다. 물론이 작업에 대부분의 시간을 소비하지 않는 한-이 경우 대신 알고리즘 작업을해야합니다. 이 목록을 얼마나 자주 만드십니까?


답변

다음은 달콤하고 단순한 (및 개념적) 두 가지 방법이고 다른 하나는보다 형식적이며 데이터 세트를 읽은 후 다양한 상황에서 확장 할 수 있습니다.

방법 1 : 개념

X2=[]
X1=[1,2,3]
X2.append(X1)
X3=[4,5,6]
X2.append(X3)
X2 thus has [[1,2,3],[4,5,6]] ie a list of lists. 

방법 2 : 공식 및 확장 가능

다른 번호 목록으로 목록을 저장하는 또 다른 우아한 방법-파일에서 읽습니다. (여기 파일에는 데이터 셋 train이 있습니다.) Train은 50 개의 행과 20 개의 열로 구성된 데이터 세트입니다. 즉. Train [0]은 csv 파일의 첫 번째 행을 제공하고 train [1]은 두 번째 행을 제공하는 식입니다. 여기에 설명 된 변수 인 0 열을 제외하고는 50 개의 행이있는 데이터 세트를 하나의 목록으로 분리하는 데 관심이 있으므로 원래 기차 데이터 세트에서 제거해야합니다. . 이를 수행하는 코드는 다음과 같습니다.

설명 변수에만 관심이 있으므로 내부 루프의 “1”에서 읽습니다. 그리고 다른 루프에서 X1 = []을 다시 초기화합니다. 그렇지 않으면 X2.append ([0 : (len (train [0])-1)])가 X1을 반복해서 다시 작성합니다.

X2=[]
for j in range(0,len(train)):
    X1=[]
    for k in range(1,len(train[0])):
        txt2=train[j][k]
        X1.append(txt2)
    X2.append(X1[0:(len(train[0])-1)])


답변

목록 및 목록 목록을 만들려면 아래 구문을 사용하십시오.

     x = [[] for i in range(10)]

이것은 1-d 목록을 생성하고 초기화하기 위해 [[number]에 숫자를 넣고 목록의 길이를 범위 (length)에 넣습니다.

  • 목록 목록을 만들려면 아래 구문을 사용하십시오.
    x = [[[0] for i in range(3)] for i in range(10)]

이것은 10 * 3 차원과 0 값으로 목록 목록을 초기화합니다.

  • 요소에 액세스 / 조작하려면
    x[1][5]=value


답변

그래서 저는 가장 빠른 방법을 얻기 위해 몇 가지 속도 비교를했습니다. 목록 이해는 실제로 매우 빠릅니다. 가까워지는 유일한 방법은 목록을 구성하는 동안 바이트 코드가 제외되지 않도록하는 것입니다. 내 첫 번째 시도는 다음과 같은 방법으로 원칙적으로 더 빠른 것으로 보입니다.

l = [[]]
for _ in range(n): l.extend(map(list,l))

(물론 길이 2 ** n의 목록을 생성합니다) timeit에 따르면이 구조는 짧은 목록과 긴 목록 (백만 개) 모두에 대해 목록 이해력보다 두 배 느립니다.

두 번째 시도는 스타 맵을 사용하여 목록 생성자를 호출하는 것이 었습니다. 목록 생성자를 최고 속도로 실행하는 것처럼 보이지만 여전히 느리지 만 아주 적은 양의 구성이 있습니다.

from itertools import starmap
l = list(starmap(list,[()]*(1<<n)))

실행 시간이 흥미 롭다는 것은 실행 시간이 다음의 속도와 거의 정확히 같기 때문에 스타 맵 솔루션을 느리게 만드는 최종 목록 호출임을 시사합니다.

l = list([] for _ in range(1<<n))

내 세 번째 시도는 list (())도 목록을 생성한다는 것을 깨달았을 때 왔기 때문에 매우 간단한 시도를했습니다.

l = list(map(list, [()]*(1<<n)))

하지만 이것은 스타 맵 호출보다 느 렸습니다.

결론 : 스피드 매니아를 위해 : 목록 이해력을 사용하십시오. 필요한 경우에만 함수를 호출하십시오. 내장 기능을 사용하십시오.


답변