Wpis z mikrobloga

Mindfuck, W pythonie, słowniki są indeksowane wartością hash obliczoną z klucza. Jako, że występuje kolizja hash'a dla 0 i False oraz odpowiednio 1 i True i 1.0, to dochodzi do poniższego zjawiska.

Wartości True i False nie mają swoich kluczy w wynikowym słowniku poniżej, bo nadpisały wartości 0 i 1.

>>> {k:k for k in (0, 1, 2, 3, 1.0, True, False, None)}
{0: False, 1: True, 2: 2, 3: 3, None: None}

Co ciekawe - jeśli zamienimy kolejność tworzenia słownika, będzie się wydawało, że wynik ma zamienione miejscami wartości z kluczami w porównaniu do poprzedniego rezultatu.

>>> {k:k for k in (True, False, 0, 1, 2, 3, 1.0, None)}
{True: 1.0, False: 0, 2: 2, 3: 3, None: None}

#python #programowanie #wscieklepiesciweza
  • 7
@tamtokontojuzusunalem: słowniki są indeksowane hashem, ale to tylko optymalizacja. Hashtable będzie działać normalnie (co prawda wolno, ale normalnie), nawet jeśli zadeklarujesz, że wszystkie wywołania hash(x) == 0. To co sie liczy, to fakt, że porównanie dla przykładowo 0 == False zwraca true
To ja się podzielę swoim mindfuckiem,
Dlaczego ta różnica w inicjalizacji tablicy daje zupełni różny wynik?
Domyślam się ze w pierwszym przypadku 2 wiersze po prostu mają wskaźnik na pierwszy wiersz dlatego wszystkie są identyczne, dobrze rozumuję ?

matrix=[[0]*3]*3
matrix[0][0]=2

for x in matrix:
print(x)

print()

matrix2=[[0,0,0],[0,0,0],[0,0,0]]
matrix2[0][0]=2

for x in matrix2:
print(x)

wynik na konsoli:
1.
[2, 0, 0]
[2, 0, 0]
[2, 0, 0]

2.
[2, 0, 0]
[0, 0,
Domyślam się ze w pierwszym przypadku 2 wiersze po prostu mają wskaźnik na pierwszy wiersz dlatego wszystkie są identyczne, dobrze rozumuję ?


@misiekkiler: Zamien zapis: matrix = [[0] * 3] * 3 na aa = [0] * 3 i nastepnie wywołaj: matrix = aa * 3 i powinno to być już jasne. Stworzyłeś listę z trzema referencjami do jednej listy aa. Stąd ta propagacja przypisania. Możesz sprawdzić: print(matrix[0] is matrix[1])