RandomPath

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.
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Sonntag 1. März 2009, 14:49

Sehr geehrtes pythonforum,
Ich möchte einen zufälligen Pfad auswählen, mein bisheriges Programm funktioniert zwar ,jedoch ist es sehr inefficent, da es bis zu einer halben Stunde dauern kann:

Code: Alles auswählen

>>> dateien=sum(([os.path.join(dirpath, filename) for filename in filenames if filename.startswith("")] for dirpath, dirnames, filenames in os.walk(r"C:\Dokumente und Einstellungen\Robin\Desktop")), [])
>>> pfaede=[]
>>> for datei in dateien:
	pfaede.append(os.path.dirname(datei))

	
>>> import random
>>> random.choice(pfaede)
'C:\\Dokumente und Einstellungen\\Robin\\Desktop\\MUKKE' #ist nur ein Beispiel
>>> 
Das ging relativ schnell, da ich nur 2 Dateienauf den Desktop habe, aber
gibt es eine schnellere Möglichkeit, die einen aus ALLEN pfäden auf dem PC auswählt?

Vielen Dank für Antworten!
Mfg Robin
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

Sonntag 1. März 2009, 15:03

Ich kenn mich nicht besonders mit Geschwindigkeitsfragen aus, aber imo wäre es schon mal schneller, wenn du nicht jeden Pfad in ``pfaede`` speichern würdest (der Plural ist afaik auch Pfade, nicht Pfäde).
Du könntest dann also einfach alle Pfade durchgehen und zufällig einen davon auswählen.
Pseudocode:

Code: Alles auswählen

x = randint()
i=1
while i <= x
  pfad = nächster_pfad
  i+=1
print pfad
Das würde dann den i-ten Pfad ausgeben ohne irgendwelche Listen zuzuspammen.
Außerdem kannst du ja selbst gucken, wo dein Programm am meisten Zeit verbraucht, indem du einfach nach jedem Programmabschnitt ein ``print time.time()-starttime`` (oder wie auch immer die Funktion war) ausgibst und schaust, welcher Teil wie lange braucht.

Man könnte auch die Möglichkeit in Betracht ziehen, einfach zufällige Anfangsbuchstaben für den nächsten Pfad-Zweig zu erstellen und diesen dann nehmen (falls existent).
Wofür du das brauchst ist mir rätselhaft, aber wahrscheinlich für sowas wie ein Zufallsmechanismus für deine Musikdateien o.Ä?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sonntag 1. März 2009, 15:17

Generell dauert das komplette Durchlaufen des Dateisystems eben - abhängig von der Anzahl an Verzeichnissen und Dateien! Insofern ist eine Indizierung ggf. schon sinnvoll.

Wofür dient denn das?

Code: Alles auswählen

... if filename.startswith("")
Und wozu dient da bei dir das sum()?

Und "pfäde" rockt einfach :-D
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Sonntag 1. März 2009, 15:17

hmm...
Gute Idee, ich werde es mal ausprobieren
Danke für den Tipp!

Ich war zu faul das auszulassen :arrow:
XD
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

Sonntag 1. März 2009, 15:27

Insofern ist eine Indizierung ggf. schon sinnvoll
Gute Idee, man kann natürlich auch soetwas wie eine Datenbank mit allen Pfaden anlegen, dann muss man eben nur ein einziges mal das gesamte Dateisystem durchforsten (bzw zur Aktualisierung wieder) und kann immer dort irgendeinen zufälligen Pfad in Sekundenbruchteilen raussuchen. Wenn man jetzt alles in eine Textdatei schreibt, könnte das auch wieder Ewigkeiten dauern, da eine Zeile auszulesen, deshalb könnte man die entweder in viele kleine Textdateien splitten oder einfach eine Datenbank benutzen.
Aber die Möglichkeit, den Pfad zufällig durch wahllose (Anfangs-)Buchstaben/Zahlen zu ergänzen gefällt mir immer noch am besten, sollte auch die eleganteste Lösung sein.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sonntag 1. März 2009, 15:40

Nocta hat geschrieben: Aber die Möglichkeit, den Pfad zufällig durch wahllose (Anfangs-)Buchstaben/Zahlen zu ergänzen gefällt mir immer noch am besten, sollte auch die eleganteste Lösung sein.
Ist aber wenig deterministisch und bei genügend großer Verzweigung auch ggf. recht langsam. Speziell bei mp3 Sammlungen, die nach Künstlername und Album gegliedert sind, ist da eine Normalverteilung ja nicht wirklich gegeben!

Amarok und co. indizieren ja auch - und das mit guten Grund!

Aber es mag durchaus vom Anwendungsfall abhängen - darüber wissen wir hier ja nix ;-)
BlackJack

Sonntag 1. März 2009, 15:48

@INFACT: Das `sum()` ist auch recht ungünstig von der Laufzeit, weil das "addieren" von Listen eine neue Liste erzeugt, also für jedes Verzeichnis alle schon bekannten Pfade kopiert werden. `reduce()` und die `list.extend()`-Methode sind da effizienter.

Sehe ich das richtig, das nicht alle Pfade gleichberechtigt sind, sondern bei der Zufallsauswahl welche mit vielen Dateien bevorzugt behandelt werden sollen!?
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Sonntag 1. März 2009, 15:53

Das sum ist nicht von mir, sondern von Leonidas

und Ja
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

Sonntag 1. März 2009, 16:08

Hyperion hat geschrieben:Ist aber wenig deterministisch und bei genügend großer Verzweigung auch ggf. recht langsam. Speziell bei mp3 Sammlungen, die nach Künstlername und Album gegliedert sind, ist da eine Normalverteilung ja nicht wirklich gegeben!
Okay, wenn jemand 5000 Musikdateien hat (und das im selben Ordner, was ich hassen würde :p), kann das vielleicht mal einen Moment dauern. Aber man muss auch bedenken, dass der Pfad dann auch fertig ist, bei einer Datei geht's eben nicht mehr verzweigter.
Und wer 5000 Ordner auf einer Ebene hat, hat auch einen an der Waffel :)
Imho sind Ordner ja genau dafür da, dass alles schön strukturiert ist und somit sind in den meisten Ordnern nur relativ wenige Dateien enthalten bzw dann in Unterordner untergliedert, was das ganze ja schon ausreichend auflockern sollte.
Dass Ordner stärker gewichtet werden sollten als Dateien ist nachvollziehbar, aber dies anhand der Anzahl der beinhaltenden Dateien zu tun, könnte das ganze ziemlich verlangsamen, weshalb ich persönlich davon absehen würde.

Ob meine Idee dann auch wirklich so schnell ist wie ich hier predige, weiß ich auch nicht, müsste man halt ausprobieren, ob das ausreichend schnell ist. Ansonsten: Indizierung.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 1. März 2009, 22:44

INFACT hat geschrieben:Das sum ist nicht von mir, sondern von Leonidas
Uh, wo? Ich bin unschuldig.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 2. März 2009, 07:24

Leonidas hat geschrieben:
INFACT hat geschrieben:Das sum ist nicht von mir, sondern von Leonidas
Uh, wo? Ich bin unschuldig.
Jaja ... das kann ja jeder sagen :-D

Aber ist ne heiße Strategie: Ab jetzt werd' ich bei unerklärbaren Fragen / Kritik auch immer schreiben, dass das von nem Profi stammt :twisted:
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Montag 2. März 2009, 08:34

Es stammt allerdings wirklich von Leonidas: http://www.python-forum.de/topic-12801.html :D
Zuletzt geändert von gkuhl am Montag 2. März 2009, 08:49, insgesamt 1-mal geändert.
BlackJack

Montag 2. März 2009, 08:43

Allerdings mit der Bemerkung `Nein, im Ernst, das würde man so nicht schreiben.`
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 2. März 2009, 10:21

Ich sollte wohl weniger komischen Code posten, denn scheinbar reichen so Warnungen nicht aus. :twisted:
My god, it's full of CARs! | Leonidasvoice vs Modvoice
_V_
User
Beiträge: 1
Registriert: Montag 2. März 2009, 19:51

Montag 2. März 2009, 21:56

Code: Alles auswählen

import os
import random

delim = "\\"
ready = False
randompath = "C:"+delim;

while ready != True:
  pathlist = [randompath+path+delim for path in [lpath for lpath in os.listdir(randompath)] if os.path.isdir(randompath+path)]
  
  if pathlist == [] or random.randint(1,10) == 1:
    ready = True
  else:
    randompath = pathlist[random.randint(0, len(pathlist)-1)]
    
print randompath
Wie wär es damit?
Wählt einfach auf jeder Ebene einen gültigen Pfad zufällig aus und geht diese Ebene tiefer wenn möglich und der Zufall es so will =)

MfG.
Antworten