Buchstaben eines Wortes in eine Liste einlesen

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.
problembär

Dienstag 27. März 2012, 23:00

Faerelis hat geschrieben:Achso und -> das ist nur ein reines testprog, ich will hier solange eine gruppe von buchstaben immer wieder neu zusammensetzen bist zufällig das wort rauskommt wie man es oben eingegeben hat.
:lol:

Spoiler ;)
EyDu
User
Beiträge: 4872
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 27. März 2012, 23:19

@problembär: Du machst es ein wenig umständlich um lediglich

Code: Alles auswählen

>>> import random
>>> a = list("Hallo")
>>> b = a[:]
>>> counter = 0
>>> while a != b:
...     counter += 1
...     random.shuffle(b)
... 
>>> print "%d Versuche" % counter
auszudrücken.

Sogar in C ist die Auswahl der Elemente mit deiner inneren while-Schleife schlecht, da für n Zeichen lediglich n Durchläufe benötigt werden. Du hast dir dort, wenn auch eine sehr unwahrscheinliche, mögliche Endlosschleife programmiert. Zur restlichen Codequalität muss man nicht viel sagen, es ist ja bekannt, dass du absichtlich gegen jegliche Idiome verstößt und das dann "Alternative" nennst.
Zuletzt geändert von EyDu am Dienstag 27. März 2012, 23:30, insgesamt 1-mal geändert.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7477
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dienstag 27. März 2012, 23:27

@problembär: Es gibt ``random.shuffle``! Dein Ersatzkonstrukt ist... naja, eher weniger gelungen. Wenn man ``shuffle`` - wieso auch immer - nachbauen wollte, dann kann man sich den Umweg über das Raten von Zahlen sparen, sondern gefundene Elemente aus einer Initialmenge solange eleminieren, bis diese leer ist (``list.pop``). Damit spart man sich das zigfache Raten von Indizes, die gar nicht mehr benötigt werden.

Das Zusammensetzen ist auch mal wieder wenig gelungen. Anstelle von diesem Trum:

Code: Alles auswählen

    c = ""
    for i in b:
        c += a[i]
    print c
kann man das doch viel einfacher so schreiben:

Code: Alles auswählen

c = "".join(a[i] for i in b)
Höre doch endlich mal auf, Dich gegen ``join`` zu wehren. Speziell in diesem Falle liegen die Vorteile wohl auf der Hand!

Idiomatischer an sich wäre die folgende Lösung: Link
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Mittwoch 28. März 2012, 09:23

Inspiriert von problembär's unpythonischer Lösung mit dem grauenhaften Shuffle-Code, hier mein unpythonischer Ansatz ((Free)Basic) mit einem Shuffle-Teil der eine deutlich vorhersehbarere Laufzeit hat:

Code: Alles auswählen

Dim As Integer i, j, wordLength, counter
Dim As String word, shuffled, tmp

Randomize

Line Input "Bitte ein Wort eingeben: ", word
wordLength = Len(word)
shuffled = word
counter = 0
Do
    counter = counter + 1
    For i=1 To wordLength
        j = Int(Rnd * wordLength) + 1
        tmp = Mid(shuffled, i, 1)
        Mid(shuffled, i, 1) = Mid(shuffled, j, 1)
        Mid(shuffled, j, 1) = tmp
    Next
    Print counter; " "; shuffled
Loop Until word = shuffled
problembär

Mittwoch 28. März 2012, 21:19

EyDu hat geschrieben:

Code: Alles auswählen

>>> import random
>>> a = list("Hallo")
>>> b = a[:]
>>> counter = 0
>>> while a != b:
...     counter += 1
...     random.shuffle(b)
... 
>>> print "%d Versuche" % counter
Find' ich auch gut/besser so. Wenn die Aufgabe aber lautete
"Sortieren Sie eine Liste nach dem Zufall neu"
wäre 'random.shuffle()' eine Killer-Methode, durch die man die Aufgabe zwar löste, aber sich zugleich auch vor ihr drückte.
In der Praxis außerhalb von Aufgaben aber eine gute Sache: Man braucht ja nichts zu schreiben, was bereits mustergültig geschrieben ist (und man braucht auch das Rad nicht noch einmal zu erfinden). Klar.
BlackJack

Mittwoch 28. März 2012, 21:23

@problembär: Bei der Aufgabenstellung "Sortieren Sie eine Liste nach dem Zufall neu" ist `random.shuffle()` genau die richtige Antwort und selber schreiben wäre Overkill, weil das in der Aufgabenstellung nicht gefordert ist.
DasIch
User
Beiträge: 2504
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Mittwoch 28. März 2012, 21:31

Selbst wenn man random.shuffle() selber schreiben muss ist eine Implementation doch wesentlich eleganter zu bewerkstelligen.

Code: Alles auswählen

# coding: utf-8
import random


def shuffled(l):
    return sorted(l, key=lambda _: random.randrange(len(l)))


def main():
    word = list(raw_input(u"Bitte ein Wort eingeben: "))
    tries = 0
    while word != shuffled(word):
        tries += 1
    print u"Es wurden %d Versuche benötigt" % tries


if __name__ == "__main__":
    main()
BlackJack

Mittwoch 28. März 2012, 21:46

@DasIch: Mir ist das heute zu spät um tatsächlich drüber nachzudenken, aber bist Du sicher dass Dein `shuffle()` unter der Voraussetzung das der Sortieralgorithmus stabil ist, nicht eventuell mehr dazu neigt Buchstaben nicht zu tauschen als `random.shuffle()`? Weil durch die Beschränkung auf ganze Zahlen im Bereich der Indexe deutlich wahrscheinlicher ist, dass man die gleiche Zahl mehr als einmal erwischt. Ich hätte da als `key` einfach nur ``lambda _: random.random()`` genommen.
DasIch
User
Beiträge: 2504
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Mittwoch 28. März 2012, 21:49

Ja, stimmt. Die Wertemenge ist so recht klein, random.random wäre da besser.
Antworten