van erre szep megoldas?
d={"a":100,"az":73,"hup":10,"abc":1,"xyz":3,"asdf":1}
for k in d:
if d[k]==1: del d[k]RuntimeError: dictionary changed size during iteration
megkerulni persze meg lehet, pl. elore lemasolni a d.keys() tombot es abban iteralni, vagy egy kulon tombbe gyujteni a torlendoket es egy masodik ciklusban csinalni a del-t...
- 419 megtekintés
Hozzászólások
d={"a":100,"az":73,"hup":10,"abc":1,"xyz":3,"asdf":1}
d2 = dict(filter(lambda item: item[1] != 1, d.items()))
print(d2)
Szerintem ennél különösebben szebb megoldás nincs.
Psszt, elárulom az IP-címemet: 192.168.0.14
- A hozzászóláshoz be kell jelentkezni
koszi, ez tenyleg szebb. ezzel csak az a baj, ha pl. egy millio elemes dictbol csak nehanyat kene kitorolni, akkor nem valami hatekony emiatt uj dict-be "atmasolni" a maradekot...
- A hozzászóláshoz be kell jelentkezni
Hat ez jogos, arra ez valoban nem lesz hatekony.
Psszt, elárulom az IP-címemet: 192.168.0.14
- A hozzászóláshoz be kell jelentkezni
Ha ilyen az arány, akkor készíts listát a törlendő kulcsokról az iteráció során, és a következő menetben töröld a lista alapján a dict elemeit.
- A hozzászóláshoz be kell jelentkezni
pontosan ezt csinalom most, csak kivancsi voltam van-e erre szebb megoldas, lehet-e az iteracio kozben torolni valahogy... C-ben lancolt listaval vagy hash tablaval megirnam siman ugy.
- A hozzászóláshoz be kell jelentkezni
Hát, írhatsz magadnak egy saját típust, ha erre van igényed :) Az kevésbé ér, hogy kézzel meg tudnám írni c-ben, mert nincs is ilyen benne, ezért kapja be a python, hogy nem azt tudja a dict megoldásuk, ami neked kell.
Cserébe nem nagyon fogod megúszni szerintem, ki kell gyűjteni a kulcsokat :(
- A hozzászóláshoz be kell jelentkezni
De ha ez baj, akkor a listából egyesével törlés még nagyobb baj, mert az is arrébb fogja másolni a lista összes hátrébb lévő elemét, minden egyes kivett elem esetén újra és újra.
- A hozzászóláshoz be kell jelentkezni
Erdemes atragni magad a kulonbozo dict init-eken, mert pl. egy comprehension majdnem biztosan hatekonyabb ennel.
- A hozzászóláshoz be kell jelentkezni
Ennyire nem ástam még bele magam a Python működésébe, a comprehension miért hatékonyabb?
Psszt, elárulom az IP-címemet: 192.168.0.14
- A hozzászóláshoz be kell jelentkezni
Mert egy lambda. Vagyis nem masolgat elotte ideiglenes teruletre, hanem kozvetlenul kerul bele elem.
Comprehension ugy nagy altalanossagban a leggyorsabb.
- A hozzászóláshoz be kell jelentkezni
Megjegyzed a pozíciót , break aztán kint delete.
zászló, zászló, szív
- A hozzászóláshoz be kell jelentkezni
Kérdés, hogy van-e pythonban tisztességes cleanup dict-ben del után. Mert nem feltétlenül "kapod vissza" azt a memóriát (fragmentáció, vagy csak simán a belső bucket-ek visszaskálázának "notimplemented" volta miatt)
- A hozzászóláshoz be kell jelentkezni
Nem biztos, hogy a memóriát akarja visszakapni :)
Egyébként bár nem túrtam soha a mélyére, de azért elég sok belső cache meg state store használja a dictet, ha elakarítod az elemre a referenciákat, akkor nem szokott elfogyni alóla mem. (Persze lehet, hogy nagyon kicsit leakel, mert csak az ojjektum takarodik el, a dict által használt bucketek vagy környékükön vmi meg nem). És ha meg elbaszod, akkor meg de :)
- A hozzászóláshoz be kell jelentkezni
Ez vsz programnyelv-fuggetlenul is egy kevesse elegans(an kinezo) dolog lesz. Legalabbis C-ben mig egy sima mezei iterator kb ilyen lehet:
for ( d = d_first; d != NULL; d = d->next )
{ do_something(d);
}
Addig a torles:
for ( d = d_first; d != NULL; )
{ item_d_t *d_next;
d_next = d->next;
if ( d->k == 1 ) delete_item(d);
d = d_next;
}
Szoval... jo kerdes...
- A hozzászóláshoz be kell jelentkezni
R-ben azért nem annyira randa:
d <- list(a = 100, az = 73, hup = 10, abc = 1, xyz = 3, asdf = 1)
d <- d[d != 1]
- A hozzászóláshoz be kell jelentkezni
Ez egy dontes kerdese, amikor tervezik a nyelvet.
Az iterator ugye olyan gyors kene, hogy legyen, amennyire lehet. Ergo, nem fer bele, hogy meg csekkelgessek, hogy "valtozott-e", es lekezeljek.
Kiveve a kifejezetten nem teljesitmenyre, hanem inkabb korrekt viselkedesre optimalizalt nyelveket/platformokat. Az R pont ilyen. Azert van ez.
- A hozzászóláshoz be kell jelentkezni
Addig a torles:
Ráadásul a fejelem törlésének a d_first-öt is módosítania kell.
De szerintem ezzel alapvetően nincs gond; az iterátor-érvényesség olyan kérdés, amivel az adatszerkezeteknél kifejezetten foglalkozni kell (... ha létezik az iterátor fogalma).
- A hozzászóláshoz be kell jelentkezni
Igen, jogos, a fenti peldabol ez kimaradt. Valojaban a delete_item egy makro ami a list headot es a torlendo elemet is megkapja mint parameter.
- A hozzászóláshoz be kell jelentkezni
Igy mondjuk? (a .keys() csak olvashatosag miatt, anelkul is jo)
>>> d={"a":100,"az":73,"hup":10,"abc":1,"xyz":3,"asdf":1}
>>> for k in list(d.keys()):
... if d[k]==1: del d[k]
...
>>> d
{'a': 100, 'az': 73, 'hup': 10, 'xyz': 3}
Ja, es mehetne list helyett tuple, kicsit eroforraskimelobb.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
igen ezt is csinaltam, csak nem szep...
megkerulni persze meg lehet, pl. elore lemasolni a d.keys() tombot es abban iteralni
- A hozzászóláshoz be kell jelentkezni
list(d.keys())
Itt csinalsz egy komplett masolatot a tobb millio elembol allo listarol. Raadasul egyesevel mesz vegig rajta, mikozben az eredeti adat egy tisztesseges hash volt.
Ennel rosszabb megoldast nehez talalni.
- A hozzászóláshoz be kell jelentkezni
d={"a":100,"az":73,"hup":10,"abc":1,"xyz":3,"asdf":1}
for k, v in list(d.items()):
if v == 1:
d.pop(k)
print(d)
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni