Inicializar uma lista de objetos em Python
-
05-07-2019 - |
Pergunta
Estou a olhar para inicializar um array / lista de objetos que não estão vazias - o construtor da classe gera dados. Em C ++ e Java eu ??faria algo assim:
Object lst = new Object[100];
Eu tenho cavado ao redor, mas há uma maneira Pythonic para conseguir este feito?
Isso não funciona como eu pensei que seria (I receber 100 referências para o mesmo objeto):
lst = [Object()]*100
Mas isso parece funcionar da maneira que eu quero:
lst = [Object() for i in range(100)]
Lista compreensão parece (intelectualmente) como "um monte" de trabalho para algo que é tão simples em Java.
Solução
Não há uma maneira de chamar implicitamente um construtor Object()
para cada elemento de uma matriz como há em C ++ (lembre-se que, em Java, cada elemento de uma nova matriz é inicializado para null
para tipos de referência).
Eu diria que o seu método de compreensão da lista é o mais Pythonic:
lst = [Object() for i in range(100)]
Se você não quiser passo no i
variável lexical, em seguida, uma convenção em Python é usar _
para uma variável dummy, cujo valor não importa:
lst = [Object() for _ in range(100)]
Para um equivalente da construção similar em Java, você pode de uso claro *
:
lst = [None] * 100
Outras dicas
Você deve observar que equvalent do Python para o código Java
(Criação de matriz de 100
Object arr = new Object[100];
ou código C ++:
Object **arr = new Object*[100];
é:
arr = [None]*100
não
arr = [Object() for _ in range(100)]
O segundo seria o mesmo que Java de:
Object arr = new Object[100];
for (int i = 0; i < arr.lenght; i++) {
arr[i] = new Object();
}
Em capacidades fato do Python para inicializar estruturas de dados complexos são muito melhores, em seguida, de Java.
Nota: código C ++:
Object *arr = new Object[100];
teria que fazer tanto trabalho como compreensão da lista de Python:
-
alocar memória contínua para 100 Objetos
-
Objeto :: Object (call) para cada um desses objetos
E o resultado seria uma estrutura de dados completamente diferente.
Eu acho que a compreensão da lista é a maneira mais simples, mas, se você não gostar dele, não é, obviamente, a única maneira de obter o que você deseja - chamando um dado que pode ser chamado 100 vezes sem argumentos para formar os 100 itens de uma nova lista. Por exemplo, itertools
pode, obviamente, fazê-lo:
>>> import itertools as it
>>> lst = list(it.starmap(Object, it.repeat((), 100)))
ou, se você é realmente um tradicionalista, map
e apply
:
>>> lst = map(apply, 100*[Object], 100*[()])
Note que este é essencialmente o mesmo (minúsculo, tanto conceitualmente e realmente ;-) quantidade de trabalho que seria necessário se, em vez de precisar de ser chamado sem argumentos, Object
precisava ser chamado com um argumento - ou, digamos , se Object
era na verdade uma função em vez de um tipo.
Desde a sua surpresa que isso pode levar "tanto quanto uma compreensão de lista" para executar esta tarefa, você parece pensar que cada linguagem deve-caso especial a necessidade de realizar "chamadas para um tipo, sem argumentos" em relação a outros tipos de chamadas para mais de chamáveis, mas não vejo o que é tão crucial e especial sobre este caso muito específico, para justificar a tratá-la de forma diferente de todos os outros; e, como conseqüência, estou muito feliz, pessoalmente, que o Python não só este caso fora para peculiar e tratamento estranho, mas alças tão regularmente e facilmente como qualquer outro caso de uso similar -!)
lst = [Object() for i in range(100)]
Uma vez que uma matriz é o seu próprio objeto de primeira classe em python Eu acho que esta é a única maneira de obter o que você está procurando. * Faz algo louco.