[Python] Dubbi su hash e set

Pietro Battiston toobaz a email.it
Ven 2 Maggio 2008 20:46:32 CEST


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ho un comando (o piuttosto il suo output) che minaccia la mia sanità
mentale:

In [6]: [v for v in penta.v][0] in  penta.v
Out[6]: False

, dove:

In [7]: type(penta.v)
Out[7]: <type 'set'>

Chiedo se un elemento di un insieme sta nella lista degli elementi di
quell'insieme e la risposta è "False"?!? Evidentemente c'è qualcosa di
grosso che mi sfugge del tipo "set", ma cosa?!

Per la cronaca:

In [8]: penta.v
Out[8]: set([(vertex 0 - edges []), (vertex 5 - edges [3, 6]), (vertex
8 - edges [9, 6]), (vertex 11 - edges [9, 12]), (vertex 14 - edges
[12, 15]), (vertex 17 - edges [3, 15]), (vertex 22 - edges [20, 23]),
(vertex 25 - edges [26, 23]), (vertex 28 - edges [26, 29]), (vertex 0
- - edges [])])

In [9]: [v for v in penta.v][0]
Out[9]: (vertex 0 - edges [])

In [10]: [v for v in penta.v][0].__class__
Out[10]: <class 'poly.vertex'>

(N.B: classe da me definita)

In [11]: id([v for v in penta.v][0])
Out[11]: 11234192

In [12]: hash([v for v in penta.v][0])
Out[12]: 0

(N.B: la funzione __hash__  di "vertex" l'ho ridefinita io)

In [13]: map(id, penta.v)
Out[13]:
[11234192,
 10002016,
 11231552,
 11232032,
 11232512,
 11232992,
 11232752,
 11231792,
 11233232,
 11233712]

In [14]: map(hash, penta.v)
Out[14]: [0, 5, 8, 11, 14, 17, 22, 25, 28, 0]

Ora, la mia coscienza sporca mi suggerisce che forse quando ho
sovrascritto __hash__ ho fatto più di quanto dovrebbe fare uno che di
internal Python non ne sa abbastanza, e che le hash di tutti gli
oggetti che conosco sono (solitamente) univoche. Ma...

In [15]: hash?
Type:        builtin_function_or_method
Base Class:    <type 'builtin_function_or_method'>
String Form:    <built-in function hash>
Namespace:    Python builtin
Docstring:
    hash(object) -> integer
   
    Return a hash value for the object.  Two objects with the same
value have
    the same hash value.  The reverse is not necessarily true, but likely.


"not necessarily true" non significa che dovrebbe alla fine fregarsene
se in un insieme due elementi distinti (e peraltro identici in tutto
tranne l'allocazione di memoria) hanno la stessa hash?!

Tra l'altro ho anche provato a cambiare il valore di hash di quegli
elementi a -2, pensando che magari dava fastidio lo 0, ma il problema
rimane.

Qualcunque schiarimento è graditissimo, scusate la chilometricità
della mail.

Già che ci sono: c'è un modo più semplice/furbo di:

elemento = [v for v in insieme][0]
oppure:
elemento = insieme.pop(); insieme.add(elemento)

per ottenere un qualsiasi elemento di un insieme dato tenendolo
nell'insieme?

grazie

Pietro
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIG2GHcZVtR82bmAYRAibPAJ9wbrRKwIBA+sN1XE9/ZGnAEDyzwQCeLcWw
FBiC9Teg4S3oe/mS3aE+h/c=
=T8oS
-----END PGP SIGNATURE-----



Maggiori informazioni sulla lista Python