2016-05-06 12 views
1

Ich habe 40.000 IDs, die die Schlüssel in einem Wörterbuch sind. Ich muss sie mischen, zum Beispiel mit random.shuffle. Aber kann ich diesen Schritt überspringen?Kann die Reihenfolge der Schlüssel eines Wörterbuchs als eine zufällige Permutation betrachtet werden?

Dictionary speichert die Schlüssel nicht mit der Reihenfolge, in der sie kommen, also wenn ich keys = dict.keys() mache, dann enthält keys die Schlüssel in einer nicht aufsteigenden Reihenfolge. Mein Programm wird nur einmal ausgeführt, also ist es mir egal, ob das "Ergebnis der Permutation" unter den Ausführungen dasselbe ist.

Also, kann ich "schummeln" und den Shuffle-Schritt überspringen?


Ich verstehe, dass die Reihenfolge der Schlüssel ein wenig vorhersehbar ist. Was ich aber frage ist das:

Was ist die Chance (grob gesagt) einer Permutation von random.shuffle() erzeugt, um (viel) identisch mit der Reihenfolge der Schlüssel zu sein?

+1

Die Wörterbuchreihenfolge ist kaum zufällig - sie ist einfach undefiniert. Sie erhalten viel bessere Ergebnisse, wenn Sie einen echten Shuffle durchführen. Die Geschwindigkeit des Mischens sollte linear sein, daher sollte die Leistung kein Problem sein. –

+0

'Die Wörterbuchreihenfolge ist kaum zufällig - sie ist nur undefiniert."; Verdammt eine Erklärung dazu wäre nett, vielleicht in einer Antwort, wenn es nicht passt? – gsamaras

+0

Ich empfehle, Hash-Tabellen und Hash-Funktionen zu lesen. Sie erhalten wahrscheinlich die Schlüssel in der Hash-Reihenfolge. –

Antwort

2

Nein, Sie können nicht.

Wenn Sie Zufälligkeit benötigen, können Sie das Mischen entweder vor dem Eingeben der Daten in das Wörterbuch oder danach nicht überspringen.

Der Grund ist, dass, obwohl die Reihenfolge der Schlüssel in einem Wörterbuch nicht garantiert ist, eine starke Vorhersagbarkeit hinsichtlich der Reihenfolge, die sie basierend auf der Reihenfolge der Eingabe annehmen wird.

Einträge in einem Wörterbuch werden nach dem Wert der hash des Schlüssels, der einige sehr große Zahl ist, Modulo eine andere große Zahl, die Schaffung eines begrenzten Wertebereich vorgenommen. Wenn zwei Schlüssel auf denselben Wert hashen, tritt ein collision auf; der Schlüssel wird dann an der nächsten verfügbaren Stelle platziert (je nachdem, welcher Weg bestimmt wird)

[edit]:
Die Chance zufällig die Schlüssel in einer ungefähr (viel) identischen Reihenfolge als ein Hash-Bucket zu bekommen ist ... unbestimmt.

2

Um zu erläutern, was andere sagen und warum Sie tatsächlich die Schlüssel mischen müssen. Wenn Sie Ihr Wörterbuch wiederholt auf die gleiche Weise initialisieren, wird es jedes Mal dieselbe Reihenfolge haben. Das ist offensichtlich nicht zufällig. Wie Masque sagte, basiert es auf dem Hash (siehe diese SO-Frage Why is the order in dictionaries and sets arbitrary?).

Um zu antworten "Was ist die Chance (grob gesagt) einer Permutation, die durch random.shuffle() erzeugt wird, um (viel) identisch mit der Reihenfolge der Schlüssel zu sein?" direkt: die Wahrscheinlichkeit, dass es ist genau identisch mit einem Shuffle ist 1/factorial(len(yourDict)); Das liegt daran, dass eine der Permutationen zu der gleichen Reihenfolge führt, die Ihr Diktat bei der Initialisierung vornimmt. Alle anderen Ordnungen werden sich jedoch unterscheiden, und es gibt factorial(len(yourDict)) verschiedene Permutationen (Ordnungen), die aus dem Mischen resultieren könnten.

Hoffe, dass hilft!

+1

Eine Quibble: Wenn das Wörterbuch überhaupt groß ist, gibt es wahrscheinlich weniger als faktorielle (len (yourDict)) mögliche Wege, den Zufallszahlengenerator zu säen, so dass die Formel übersteuert, was direkt mit 'random.shuffle() möglich ist. '. Siehe diese Frage: http://Stackoverflow.com/q/34139259/4996248 Auch, zum Spaß, siehe: https://www.youtube.com/watch?v=T69cguFzZ_w –

+0

Sehr cool. OP sagt jedoch, dass sie nur mit 40.000 IDs zu tun haben, und die Pseudozufallszahlengenerierungsdauer wird für Python wie folgt angegeben: "2 ** 19937-1". Sie sollten also auf lange Sicht sicher sein. – rofls

+1

Summe (math.log (n, 2) für n im Bereich (1,40001)) ergibt 553809, also 40000! ist mehr wie 2 ** 553809. Wenn die Systemuhr außerdem so eingestellt ist, dass der Shuffle eine Funktion des Systemtakts zum Zeitpunkt des Seeding ist, dann ist die Anzahl der möglichen Zustände der Systemuhr winzig im Vergleich zu 40.000! (oder sogar 52!), was nahelegt, dass 'random.shuffle()' niemals mehr tun kann, als die Oberfläche aller mathematisch möglichen Shuffle zu scratchen. –