Domanda

Sto cercando di inizializzare un array / elenco di oggetti che non sono vuoti: il costruttore della classe genera dati. In C ++ e Java farei qualcosa del genere:

Object lst = new Object[100];

Ho cercato, ma esiste un modo Pythonic per farlo?

Questo non funziona come pensavo (avrei ricevuto 100 riferimenti allo stesso oggetto):

lst = [Object()]*100

Ma questo sembra funzionare nel modo in cui voglio:

lst = [Object() for i in range(100)]

La comprensione dell'elenco sembra (intellettualmente) come "molto" di lavoro per qualcosa di così semplice in Java.

È stato utile?

Soluzione

Non c'è modo di chiamare implicitamente un costruttore Object () per ogni elemento di un array come in C ++ (ricordate che in Java, ogni elemento di un nuovo array è inizializzato su null per i tipi di riferimento).

Direi che il tuo metodo di comprensione dell'elenco è il più Pythonic:

lst = [Object() for i in range(100)]

Se non vuoi fare un passo sulla variabile lessicale i , una convenzione in Python consiste nell'usare _ per una variabile fittizia il cui valore non ha importanza :

lst = [Object() for _ in range(100)]

Per un equivalente del costrutto simile in Java, puoi ovviamente usare * :

lst = [None] * 100

Altri suggerimenti

Dovresti notare che Python è equivalente per il codice Java (creazione di una matrice di 100 null riferimenti a Object):

Object arr = new Object[100];

o codice C ++:

Object **arr = new Object*[100];

è:

arr = [None]*100

non

arr = [Object() for _ in range(100)]

Il secondo sarebbe lo stesso di Java:

Object arr = new Object[100];
for (int i = 0; i < arr.lenght; i++) {
    arr[i] = new Object();
}

In effetti le capacità di Python di inizializzare strutture di dati complesse sono molto meglio di quelle di Java.


Nota: Codice C ++:

Object *arr = new Object[100];

dovrebbe fare tanto lavoro quanto la comprensione dell'elenco di Python:

  • alloca memoria continua per 100 oggetti

  • chiama Object :: Object () per ciascuno di questi oggetti

E il risultato sarebbe una struttura di dati completamente diversa.

Penso che la comprensione dell'elenco sia il modo più semplice, ma, se non ti piace, ovviamente non è l'unico modo per ottenere ciò che desideri: chiamare un dato callable 100 volte senza argomenti per formare i 100 elementi di un nuovo elenco. Ad esempio, itertools può ovviamente farlo:

>>> import itertools as it
>>> lst = list(it.starmap(Object, it.repeat((), 100)))

o, se sei davvero un tradizionalista, map e si applicano :

>>> lst = map(apply, 100*[Object], 100*[()])

Nota che questa è essenzialmente la stessa (piccola, sia concettualmente che effettivamente ;-) quantità di lavoro che ci vorrebbe se, invece di dover essere chiamato senza argomenti, Object dovesse essere chiamato con un argomento - o, diciamo, se Object era in effetti una funzione piuttosto che un tipo.

Dalla tua sorpresa, potrebbe essere necessario "tanto quanto una comprensione dell'elenco" per eseguire questo compito, sembra che tu pensi che ogni lingua dovrebbe in casi particolari la necessità di eseguire "chiamate a un tipo, senza argomenti" rispetto ad altri tipi di chiamate a over callable, ma non riesco a vedere cosa sia così cruciale e speciale in questo caso molto specifico, per giustificare il trattamento in modo diverso da tutti gli altri; e, di conseguenza, sono abbastanza felice, personalmente, che Python non scelga questo caso per un trattamento strano e strano, ma gestisca altrettanto regolarmente e facilmente come qualsiasi altro caso d'uso simile! -)

lst = [Object() for i in range(100)]

Poiché un array è il suo oggetto di prima classe in Python, penso che questo sia l'unico modo per ottenere ciò che stai cercando. * fa qualcosa di folle.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top