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

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

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: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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

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

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: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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

@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

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

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
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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 (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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

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

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

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

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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@_V_: Wirf mal einen Blick auf "os.path.join".

Aus dem "while ready != True:" solltest du ein "while not ready:" machen, oder ein "while True:" und dann die Scheife mit break verlassen.

Die innere List-comprehension ist überflüssig, da reicht auch "os.listdi(randompath)".

Warum wird die Schleife mit einer WK 1/9 beendet, ohne das Ende erreicht zu haben?

Deine Herangehensweise liefert außerdem keine Gleichverteilung über alle Dateien.
Das Leben ist wie ein Tennisball.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Pfade setzt man mit ``os.path.join`` zusammen. Mein System hat auch keine Ahnung was denn ein ``C:\irgendwas`` überhaupt sein soll. Also ein Pfad ists schon mal nicht :twisted:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@Leonidas: Dann leg den Pfad halt an:

Code: Alles auswählen

bj@s8n:~$ mkdir 'C:\irgendwas'
bj@s8n:~$ ls -l 'C:\irgendwas'
total 0
Und schon gibt's den auch auf Deinem System. ;-)
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Der ist Gut!
Danke @all
So was habe ich gesucht.
MfG
Infact
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
Antworten