list comprehension über set instabil
Verfasst: Donnerstag 16. November 2023, 15:38
Hallo, das Verhalten des folgenden Kodes finde ich merkwürdig.
Ich würde erwarten, dass li_c in der Reihenfolge des sets s gebildet wird. Tatsächlich aber, wird es zufällig und abhängig von der aktuellen Python-Interpreter Instanz gebildet.
Also mehrfaches ausführen des .py führt zu anderen Reihenfolgen in li_c, während innerhalb einer Ausführung immer die gleiche Reihenfolge besteht, wie diese Ausgabe zeigt.
Andere Python-Interpreter Instanz, selber Kode
Anm..: Verwendet man anstelle von datetime einen einfachen Datentyp z.B. int bleibt es stabil. Allerdings kann ich da keinen Zusammenhang sehen.
Getestet gegen 3.9.2 / 3.10.12 Linux und 3.10.4 Windows.
Frage: Würdet ihr dieses Verhalten erwarten und wenn ja, wieso?
Code: Alles auswählen
import datetime
from icecream import ic
def why_unstable():
li = [datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)]
ic(li)
for i in range(3):
s=set(li)
ic(s)
li_c=[x for x in s]
ic(li_c)
if __name__ == '__main__':
why_unstable()
exit()
Also mehrfaches ausführen des .py führt zu anderen Reihenfolgen in li_c, während innerhalb einer Ausführung immer die gleiche Reihenfolge besteht, wie diese Ausgabe zeigt.
Code: Alles auswählen
ic| li: [datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)]
ic| s: {datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)}
ic| li_c: [datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0)]
ic| s: {datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)}
ic| li_c: [datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0)]
ic| s: {datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)}
ic| li_c: [datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0)]

Code: Alles auswählen
ic| s: {datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)}
ic| li_c: [datetime.datetime(2021, 1, 1, 12, 0),
datetime.datetime(2020, 1, 1, 12, 0),
datetime.datetime(2022, 1, 1, 12, 0)]
Getestet gegen 3.9.2 / 3.10.12 Linux und 3.10.4 Windows.
Frage: Würdet ihr dieses Verhalten erwarten und wenn ja, wieso?