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

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

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

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

[[]]*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))

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

Ответ 1

Вероятно, только путь, который немного быстрее, чем

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

является

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

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

Изменить. Используя NumPy, вы можете избежать цикла Python, используя

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

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

Ответ 2

Реализации на самом деле реализованы более эффективно, чем явный цикл (см. вывод dis, например, функции) и способ map должен ссылаться на объект, вызывающий сомнение, на каждой итерации, что несет значительные накладные расходы.

Несмотря на это, [[] for _dummy in xrange(n)] - это правильный способ сделать это, и ни одна из крошечных (если вообще существует) разница в скорости между различными способами должна иметь значение. Если, конечно, вы не проводите большую часть своего времени, но в этом случае вместо этого вы должны работать над своими алгоритмами. Как часто вы создаете эти списки?

Ответ 3

Вот два метода: один сладкий и простой (и концептуальный), другой более формальный и может быть расширен в различных ситуациях после чтения набора данных.

Метод 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 столбцов. то есть. Поезд [0] дает мне 1-ю строку файла csv, поезд [1] дает мне 2-й ряд и так далее. Меня интересует разделение набора данных на 50 строк как один список, за исключением столбца 0, который является моей объясненной переменной здесь, поэтому его необходимо удалить из набора данных orignal 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)])

Ответ 4

Чтобы создать список и список списков, используйте синтаксис ниже

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

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

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

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

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

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

    х [1] [5] = значение

Ответ 5

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

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

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

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

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

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

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

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

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

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

Заключение: для маньяков скорости: Используйте понимание списка. Только вызовы, если вам нужно. Используйте встроенные функции.