zufälliges schlüssel/wert-paar aus dict ausgeben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
gehirn
User
Beiträge: 5
Registriert: Mittwoch 3. September 2008, 16:37

nabend

ich versuche gerade, ein zufälliges schlüssel/wert- paar eines dicts auszugeben, ohne dass es danach entfernt wird, also popitem() erfüllt den zweck nicht.

danke für eure ideen.

gehirn
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Spontan faellt mir da

Code: Alles auswählen

random.choice(my_dict.items())
ein.

:wink:
yipyip
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

gehirn hat geschrieben:also popitem() erfüllt den zweck nicht.
Auch wenn du das Element entfernen wolltest, würde es deinen Anforderungen nicht entsprechen. "popitem" nimmt ein *beliebiges* Element aus dem Dictionary aber kein zufälliges.
gehirn
User
Beiträge: 5
Registriert: Mittwoch 3. September 2008, 16:37

@yipyip: ist dein vorschlag bei großen dicts nicht zu langsam? es wir ja jedesmal das ganze dingen kopiert.
BlackJack

Es kommt darauf an was "zu langsam" im konkreten Fall bedeutet.
gehirn
User
Beiträge: 5
Registriert: Mittwoch 3. September 2008, 16:37

ob es keine schnellere methode gibt, soll das bedeuten.
BlackJack

Eventuell:

Code: Alles auswählen

key = random.choice(dictionary.keys())
value = dictionary[key]
Kann aber auch langsamer sein, weil mehr Python-Bytecodes ausgeführt werden.

Letztendlich ist ein Dictionary halt für so einen Zugriff nicht geeignet, wenn's effizient sein soll.

Aber wie gesagt: Es kommt auf den konkreten Einsatz an, ob's *zu* langsam ist.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Python 3.0 hat da den Vorteil dass keys() und items() Dictionary-Views sind und nicht immer neue Listen, was der Performance und dem geringerem Speicherverbrauch zuträglich ist.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
abgdf

Wie wär's:

Code: Alles auswählen

import random

a = {"a" : "1", "b" :"2", "c": "3"}

b = a.keys()
random.shuffle(b)

for i in b:
    print a[i]
?

Gruß
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Wusste mal wieder nicht, dass es um pure Geschwindigkeit geht.

Ein kleines Rennen:

Code: Alles auswählen

import time
import random

n = 1000
m = 1000
d = dict(zip(xrange(n), xrange(n)))

start = time.time()

for i in xrange(m):
  v = random.choice(d.items())

print time.time() - start


start = time.time()

for i in xrange(m):
  c = random.choice(d.keys())
  v = d[c]

print time.time() - start

start = time.time()

for i in xrange(m):
  k = d.keys()
  random.shuffle(k)
  v = d[k[0]]
       
print time.time() - start
ergibt:
0.0767362117767
0.0145328044891
1.34616398811
Der Sieger ist: BlackJack !

:wink:
yipyip
epsilon
User
Beiträge: 71
Registriert: Freitag 20. Juni 2008, 19:48

@ gehirn:

musst du überhaupt per key auf die Werte im dict zugreifen?
Ansonsten würde ich eher eine Liste aus tuples verwenden, wenn es dir auf Performance ankommt.

Code: Alles auswählen

l = zip(xrange(n), xrange(n))

start = time.time() 
for i in xrange(m): 
  v = random.choice(l)[1]
print time.time() - start
an das Skript von yipyip dran gehängt ergibt

0.0918290615082
0.0164000988007
1.32954907417
0.00253510475159
Antworten