A prima vista, sembra che x
voglia sempre uguale y
, perché due insiemi costruiti dagli stessi elementi sono sempre uguali:
>>> x = set([1, "a", "b", "c", "z", "f"])
>>> y = set(["a", "b", "c", "z", "f", 1])
>>> x
{1, 'z', 'a', 'b', 'c', 'f'}
>>> y
{1, 'z', 'a', 'b', 'c', 'f'}
>>> x == y
True
Tuttavia, è non sempre il caso che tuple (o altre raccolte ordinate) costruite da due serie uguali sono uguali.
In effetti, il risultato del confronto è talvolta True
e talvolta False
, almeno in Python> = 3.3. Testare il codice seguente:
# compare.py
x = tuple(set([1, "a", "b", "c", "z", "f"]))
y = tuple(set(["a", "b", "c", "z", "f", 1]))
print(x == y)
... mille volte:
$ for x in {1..1000}
> do
> python3.3 compare.py
> done | sort | uniq -c
147 False
853 True
Questo perché, dal momento che Python 3.3, i valori di hash di stringhe, byte e datetimes sono randomizzati a seguito di un security fix. A seconda di cosa sono gli hash, possono verificarsi "collisioni", il che significa che gli articoli dell'ordine sono memorizzati nell'array sottostante (e quindi l'ordine di iterazione) dipende dall'ordine di inserimento.
Ecco il bit rilevante dalla documentazione:
miglioramenti di sicurezza:
- Hash randomizzazione è attivata per impostazione predefinita.
- https://docs.python.org/3/whatsnew/3.3.html
EDIT: Dal momento che è menzionato nei commenti che il rapporto True
/False
sopra è superficialmente sorprendente ...
insiemi, come dizionari, vengono implementate come hash tabelle - quindi se c'è una collisione, l'ordine degli elementi nella tabella (e quindi l'ordine di iterazione) dipenderà sia dall'elemento che è stato aggiunto per primo (diverso in x
e in t il suo caso) e il seme utilizzato per l'hashing (diverso per le invocazioni di Python dal 3.3). Dato che le collisioni sono rare per progettazione e gli esempi in questa domanda sono insiemi piccoli, il problema non si pone tutte le volte che si potrebbe supporre inizialmente.
Per una spiegazione completa dell'implementazione di Python di dizionari e insiemi, vedere The Mighty Dictionary.
perché ti aspetti che sia False - il contenuto dei due set è lo stesso! –
[Relevant.] (Http://stackoverflow.com/a/26099671/1763356) Come dice Zero Pireo, tuttavia, la randomizzazione dell'hash rende questa falsità ** per stringhe, byte e date ** come 'hash (a_string)' cambia ogni volta che installi l'interprete. – Veedrac