For-loop i python beter sig konstigt

Permalänk
Medlem

For-loop i python beter sig konstigt

Jag försöker sortera ut projekt (dictionaries) ur en lista baserat på vilka tekniker de innehåller. För att felsöka printar jag ut vilka projekt-IDn som loopas men jag blir inte klok på det. Söker jag python looper den igenom alla fyra projekt men söker jag ada går den som högst igenom tre. Hur jag än gör behålls projektet "NEJ"... Någon som kan se vad som är fel?

python tutor

Visa signatur

Case: Lian Li PC-O11 Dynamic - Motherboard: MSI MAG X570 TOMAHAWK WIFI - CPU: AMD Ryzen 5 3600 - GPU: Gainward GeForce RTX 3080 Phantom 10G - RAM: G.Skill 32GB DDR4 3600MHz CL18 Trident Z Neo - PSU: Corsair RM750X - SSD: Kingston A2000 1TB

Permalänk
Medlem

Du kommer få sånt oväntat beteende när du börjar ta bort saker ur en dictionary medans du itererar den.

Iterera en kopia av listan, och ta bort från originalet.
Byt ut

for project in db: print("id = " + str(project["project_id"])) if technique not in project["techniques_used"]: db.remove(project)

med

for project in db[:]: #Will make copy of db dict to iterate print("id = " + str(project["project_id"])) if technique not in project["techniques_used"]: db.remove(project)

Visa signatur

Ryzen 5600X | MSI Tomahawk | GTX 3070

Permalänk
Medlem

@Sonywalk: Tack! Förstår inte alls varför men skönt att det funkar nu.

Visa signatur

Case: Lian Li PC-O11 Dynamic - Motherboard: MSI MAG X570 TOMAHAWK WIFI - CPU: AMD Ryzen 5 3600 - GPU: Gainward GeForce RTX 3080 Phantom 10G - RAM: G.Skill 32GB DDR4 3600MHz CL18 Trident Z Neo - PSU: Corsair RM750X - SSD: Kingston A2000 1TB

Permalänk
Medlem

@Murvar: Tänkte bara flika in att detta är en typisk filtrering, vilket i Python vanligtvis görs med en list comprehension.

filtered_db = [ project for project in db if technique not in project["techniques_used"] ]

Jag rekommenderar starkt att du lär dig list/dictionary/set comprehensions, RealPython har en väldigt bra artikel om det.

Alternativt kan man använda den inbyggda filter-funktionen, men jag tycker personligen det blir mindre läsbart då lambdas är så... oläsbara.

filtered_db = list( filter(lambda project: technique not in project["techniques_used"], db) )

Permalänk
Medlem

Man ska (nästan) aldrig ändra i en lista medan man itererar (loopar) över den, eftersom det lätt blir fel och element i listan kan hopps över om man inte gör exakt rätt