Python: самый быстрый способ создать список из n списков


поэтому мне было интересно, как лучше всего создать список пустых списков:

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

из-за того, как Python работает со списками в памяти, это не работает:

[[]]*n

это создает [[],[],...] но каждый элемент-это один и тот же список:

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

что-то вроде списка понимание работает:

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

но при этом используется виртуальная машина Python для зацикливания. Есть ли способ использовать подразумеваемый цикл (воспользовавшись тем, что он написан в В)?

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

это на самом деле медленнее. : (

5 75

5 ответов:

вероятно, единственный способ, который намного быстрее, чем

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

и

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

он не должен создавать новый int объект в каждой итерации и примерно на 5 % быстрее на моей машине.

Edit: используя NumPy, вы можете избежать цикла Python с помощью

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

но это на самом деле в 2,5 раза медленнее, чем понимание списка.

понимание списка на самом деле реализуется более эффективно, чем явный цикл (см. the dis выводить, например, функции) и map way должен вызывать вызываемый объект 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: формальный и расширяемый

еще один элегантный способ хранения списка в виде списка списков различных чисел-которые он читает из файла. (Файл здесь имеет набор данных поезд) Поезд представляет собой набор данных с скажем 50 строк и 20 столбцов. то есть. Train[0] дает мне 1-ю строку csv-файла, train[1] дает мне 2-ю строку и так далее. Я заинтересован в разделении набора данных с 50 строками в виде одного списка, за исключением столбца 0 , который является моей объясненной переменной здесь, поэтому должен быть удален из исходного набора данных train, а затем масштабировать список после списка - т. е. список списка. Вот код, который это делает.

обратите внимание, что я читаю из "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)])

поэтому я сделал некоторые сравнения скорости, чтобы получить самый быстрый способ. Список постижений действительно очень быстро. Единственный способ приблизиться-это избежать выполнения байт-кода во время построения списка. Моей первой попыткой был следующий метод, который в принципе оказался бы быстрее:

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

(производит список длины 2* * n, конечно) Эта конструкция в два раза медленнее, чем понимание списка, согласно timeit, как для коротких, так и для длинных (a миллион) списков.

моя вторая попытка была использовать starmap для вызова конструктора списка для меня, есть одна конструкция, которая, кажется, запускает конструктор списка на максимальной скорости, но все же медленнее, но только на небольшую сумму:

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

достаточно интересно время выполнения предполагает, что именно последний вызов списка делает решение starmap медленным, так как его время выполнения почти точно равно скорости:

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

моя третья попытка вышла когда я понял, что list (()) также создает список, поэтому я попробовал apperently простой:

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

но это было медленнее, чем вызов starmap.

вывод: для скоростных маньяков: Используйте понимание списка. Вызывайте только функции, если это необходимо. Используйте встроенные модули.

для создания списка и списка списков используйте синтаксис ниже

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

это создаст 1-d список и инициализировать его положить номер в [[номер] и установить длину списка положить длину в диапазоне (длина)

  • для создания списка списков используйте следующий синтаксис.

    x = [[[0] для i в диапазоне(3)] для i в диапазоне(10)]

это инициализирует список списков с размером 10*3 и со значением 0

  • для доступа/манипулирования элемент

    x[1] [5]=value