Sto creando un metodo veloce per generare un elenco di numeri primi nell'intervallo (0, limite + 1). Nella funzione finisco per rimuovere tutti gli interi nell'elenco chiamato rimovibile dalla lista chiamata primi. Sto cercando un modo veloce e pitonico per rimuovere gli interi, sapendo che entrambe le liste sono sempre ordinate.Cos'è un modo veloce e pitonioso/pulito per rimuovere una lista ordinata da un'altra lista ordinata in python?
Potrei sbagliarmi, ma credo che list.remove (n) itera sulla lista confrontando ogni elemento con n. il che significa che il codice seguente viene eseguito in tempo O (n^2).
# removable and primes are both sorted lists of integers
for composite in removable:
primes.remove(composite)
in base al largo la mia ipotesi (che potrebbe essere sbagliato e si prega di confermare o meno questo è corretto) e il fatto che entrambe le liste sono sempre ordinati, penserei che il seguente codice corre più veloce, dal momento che solo i loop sulla lista una volta per un tempo O (n). Tuttavia, non è affatto pitonico o pulito.
i = 0
j = 0
while i < len(primes) and j < len(removable):
if primes[i] == removable[j]:
primes = primes[:i] + primes[i+1:]
j += 1
else:
i += 1
C'è forse una funzione incorporata o un modo più semplice per farlo? E qual è il modo più veloce?
Note a margine: in realtà non ho programmato le funzioni o il codice riportato sopra. Inoltre, non importa se l'elenco rimovibile viene modificato/distrutto nel processo.
Per chiunque sia interessato le funzioni completo è qui sotto:
import math
# returns a list of primes in range(0, limit+1)
def fastPrimeList(limit):
if limit < 2:
return list()
sqrtLimit = int(math.ceil(math.sqrt(limit)))
primes = [2] + range(3, limit+1, 2)
index = 1
while primes[index] <= sqrtLimit:
removable = list()
index2 = index
while primes[index] * primes[index2] <= limit:
composite = primes[index] * primes[index2]
removable.append(composite)
index2 += 1
for composite in removable:
primes.remove(composite)
index += 1
return primes
una singola chiamata a 'corre primes.remove' in' O (n) 'tempo , quindi la tua 2a soluzione pulita gira anche in tempo 'O (n^2)', non più veloce della prima. È possibile farlo nel tempo 'O (n)', in modo simile alla tua seconda soluzione, ripetendo simultaneamente su entrambe le liste (con variabili di ciclo 'i' e' j', incrementando solo una di esse alla volta), ma costruendo una lista di output separata. – pts
Scusa volevo cambiare primes.remove() in primes = primes [: i] + primi [i + 1:] – DavidC
Dai un'occhiata alla [soluzione di Robert William Hank] (http://stackoverflow.com/a/3035188/190597). Usa una lista booleana e imposta gli elementi su False quando viene determinato che (approssimativamente) l'indice di quell'elemento non è un numero primo. – unutbu