Então, eu queria saber a melhor forma de criar uma lista de listas em branco:
[[],[],[]...]
Por causa de como o Python funciona com listas na memória, isso não funciona:
[[]]*n
Isso cria, [[],[],...]
mas cada elemento é a mesma lista:
d = [[]]*n
d[0].append(1)
#[[1],[1],...]
Algo como a compreensão de uma lista funciona:
d = [[] for x in xrange(0,n)]
Mas isso usa o Python VM para loop. Existe alguma maneira de usar um loop implícito (aproveitando que ele está escrito em C)?
d = []
map(lambda n: d.append([]),xrange(0,10))
Na verdade, isso é mais lento. :(
d = [[] for x in xrange(0,n)]
. Você precisa fazer um loop explicitamente no Python ou chamar uma função / lambda do Python repetidamente (que deve ser mais lenta). Mas ainda espero que alguém poste algo que mostre que estou errado :).timeit
, o que você aprendeu?map(lambda x: [], xrange(n))
é mais lento do que a compreensão de uma lista.Respostas:
Provavelmente a única maneira que é ligeiramente mais rápida do que
é
Não é necessário criar um novo
int
objeto a cada iteração e é cerca de 15% mais rápido na minha máquina.Editar : usando NumPy, você pode evitar o loop Python usando
mas isso é na verdade 2,5 vezes mais lento do que a compreensão da lista.
fonte
map(lambda x:[], repeat(None,n))
?As compreensões de lista, na verdade, são implementadas de forma mais eficiente do que o loop explícito (consulte a
dis
saída para funções de exemplo ) e amap
maneira deve invocar um objeto opaco que pode ser chamado em cada iteração, o que incorre em um overhead considerável.Independentemente disso,
[[] for _dummy in xrange(n)]
é a maneira certa de fazer isso e nenhuma das pequenas (se existentes) diferenças de velocidade entre as várias outras maneiras deveriam importar. A menos, claro, que você gaste a maior parte do seu tempo fazendo isso - mas, nesse caso, você deve trabalhar em seus algoritmos. Com que frequência você cria essas listas?fonte
_
como um nome de variável! Caso contrário, boa resposta :)i
, eu estaria procurando onde é usado). A única armadilha seria que ele obscurece a_
realização do último resultado no REPL ... e isso é apenas o caso em 2.x onde as compreensões de lista vazam._
no interpretador interativo, ele também conflita com o alias gettext comum. Se você quiser deixar claro que a variável é uma variável fictícia, chame-adummy
, não_
.Aqui estão dois métodos, um doce e simples (e conceitual), o outro mais formal e pode ser estendido em uma variedade de situações, após a leitura de um conjunto de dados.
Método 1: conceitual
Método 2: formal e extensível
Outra maneira elegante de armazenar uma lista como uma lista de listas de números diferentes - que ela lê de um arquivo. (O arquivo aqui tem o trem do conjunto de dados) Trem é um conjunto de dados com, digamos, 50 linhas e 20 colunas. ie. Train [0] me dá a 1ª linha de um arquivo csv, train [1] me dá a 2ª linha e assim por diante. Estou interessado em separar o conjunto de dados com 50 linhas como uma lista, exceto a coluna 0, que é minha variável explicada aqui, portanto, deve ser removido do conjunto de dados do trem original e, em seguida, aumentar lista após lista - ou seja, uma lista de uma lista . Aqui está o código que faz isso.
Observe que estou lendo "1" no loop interno, pois estou interessado apenas em variáveis explicativas. E eu reinicializo X1 = [] no outro loop, senão o X2.append ([0: (len (train [0]) - 1)]) irá reescrever X1 repetidamente - além de ser mais eficiente em termos de memória.
fonte
Para criar uma lista e uma lista de listas, use a sintaxe abaixo
isto irá criar uma lista 1-d e para inicializá-la coloque o número em [[número] e definir o comprimento da lista colocar o comprimento no intervalo (comprimento)
isso inicializará a lista de listas com dimensão 10 * 3 e com valor 0
fonte
Então, fiz algumas comparações de velocidade para obter o caminho mais rápido. As compreensões de listas são realmente muito rápidas. A única maneira de chegar perto é evitar que o bytecode seja executado durante a construção da lista. Minha primeira tentativa foi o seguinte método, que parece ser mais rápido em princípio:
(produz uma lista de comprimento 2 ** n, é claro) Esta construção é duas vezes mais lenta do que a compreensão da lista, de acordo com o tempo, para listas curtas e longas (um milhão).
Minha segunda tentativa foi usar o starmap para chamar o construtor de lista para mim. Há uma construção, que parece executar o construtor de lista em alta velocidade, mas ainda é mais lento, mas apenas por uma pequena quantidade:
Curiosamente, o tempo de execução sugere que é a chamada de lista final que torna a solução do mapa estelar lenta, já que seu tempo de execução é quase exatamente igual à velocidade de:
Minha terceira tentativa veio quando percebi que list (()) também produz uma lista, então tentei o aparentemente simples:
mas isso foi mais lento do que a chamada do mapa estelar.
Conclusão: para os maníacos por velocidade: Use a compreensão de lista. Apenas chame funções, se for necessário. Use builtins.
fonte