[Python] Il dilemma degli array mutabili
Riccardo Lemmi
riccardo a reflab.com
Gio 19 Set 2013 17:58:05 CEST
Piergiuliano Bossi wrote:
> 2013/9/18 Riccardo Lemmi <riccardo a reflab.com>
>
>>
>>
>> Mi sfugge il caso, forse un esempio chiarirebbe... L'unico posto in
>> cui vedo male il codice messo sopra è quello in cui si usano gli
>> elementi dell'array non in sequenza ma pescando in "qua e la'"
>>
>>
> Ho visto la luce.
>
> Questo e' il codice che ha causato il thread (semplificato,
> ovviamente);
>
> def evaluate(list):
> return sum(v for v in list if v % 2 == 0)
>
> def _subtract(list1, list2):
> result = list1[:]
> for val in list2:
> result.remove(val)
> return result
Manca un check prima di fare il remove. Alternativamente la scriverei
così:
def _subtract(list1, list2):
result = []
for val in list2:
if val not in list2:
result.append(val)
return result
ma se non ci sono ridondanze nelle due liste cioè stai effettivamento
implementando la differenza fra insiemi:
result = set(list1) - set(list2)
o
result = set(list1).difference(list2)
> def useless(list):
> useful = list[:]
> for val in list:
> useful.remove(val)
> if evaluate(useful) != evaluate(list):
> useful.append(val)
> return _subtract(list, useful)
>
> if __name__ == "__main__":
> print(useless([])) # => []
> print(useless([1, 2, 3, 5, 8])) # => [1, 3, 5]
>
> Codice abbastanza orrido, no?
>
> L'idea e' calcolare gli elementi di una lista che non contribuiscono
> al valore determinato da una certa funzione. Diciamo che evaluate in
> realta' e' molto piu' complessa (non computazionalmente, ma
> matematicamente non e' semplice), che e' insensibile all'ordine degli
> elementi nella lista (da cui l'uso di remove non posizionale) e che
> ovviamente questo codice non e' ottimizzato (eg: e' inutile chiamare
> evaluate(list) ogni volta nel ciclo).
>
detto così sembra proprio che tu stia lavorando con i set...
> L'ho riscritto senza copy.copy ma con [:] e ovviamente tutto bene, ma
> non e' un gran guadagno. Poi ho provato a fare una comprehension che
> fa tutto al volo e mi e' venuta al primo colpo:
>
> def useless(list):
> return [list[i] for i in range(len(list)) if evaluate(list[:i] +
> list[i+1:]) == evaluate(list)]
>
> Oserei dire che e' persino un pelo piu' comunicativa cosi', visto che
> non devo calcolare una lista e poi sottrarla all'altra.
> Mi sento come se avessi trovato il barattolo di nutella di Moretti, un
> cucchiaione e nessuno attorno... :)
>
> Ciao
> Giuliano
>
> PS: queste sono le cose che fanno scattare l'ammmmore...
>
>
--
Riccardo Lemmi
Maggiori informazioni sulla lista
Python