set in liste umwandlen und andere Operationen

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

set in liste umwandlen und andere Operationen

Beitragvon klaus » Donnerstag 17. Juli 2008, 18:13

Hi Leute,
ich wollte fragen, ob es möglich ist ein set wieder in eine liste umzuwandeln, und wenn ja, wie.

Außerdem wäre es nett, wenn ihr mir sagen könntet, wie ich es schaffe, in eine Liste aus natürlichen Zahlen (z.B. [1, 2, 3, 8, 9, 10, 11, 12, 34, 35, 36]) immer an den Stellen, an denen zwei nicht aufeinanderfolgenden Zahlen stehen den Wert "True" einzufügen. Das Ergebnis sollte dann so aussehen:
[1, 2, 3, True, 8, 9, 10, 11, 12, True, 34, 35, 36]

Bin für jeden Hilfe dankbar.
EyDu
User
Beiträge: 4868
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Donnerstag 17. Juli 2008, 18:44

Du kannst mit der list-Funktion aus einer Menge wieder eine Liste machen.

Zur zweiten Frage:

Code: Alles auswählen

for a, b in zip(liste, liste[1:]):
    print a, b
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Beitragvon klaus » Freitag 18. Juli 2008, 17:16

Danke für die schnelle Antwort, allerdings habe ich jetzt auch einen anderen Weg gefunden, das Problem zu lösen:

Code: Alles auswählen

def prepare(x):
    for n in x:
        if not n:
            continue
        i = x.index(n) + 1
        try:
            n1 = x[i]
        except IndexError:
            continue
        if n+1 != n1:
            x.insert(i, False)
    return x


Aber ich werde trotzdem mal einen Test machen, ob meine Lösung, bei der ich zuerst wieder den Index ermittle und dann den nachfolgenden Index auslese mehr Resourcen verbraucht, als die Lösung über die Funktion zip().
BlackJack

Beitragvon BlackJack » Freitag 18. Juli 2008, 18:06

Also ich find's recht unübersichtlich und ausserdem würde ich eher eine neue Liste aufbauen, als die alte zu verändern.

Code: Alles auswählen

def prepare(numbers):
    numbers = iter(numbers)
    a = numbers.next()
    for b in numbers:
        yield a
        if b - a > 1:
            yield False
        a = b
    yield a


Tests:

Code: Alles auswählen

In [157]: list(prepare([]))
Out[157]: []

In [158]: list(prepare([1]))
Out[158]: [1]

In [159]: list(prepare([1,2]))
Out[159]: [1, 2]

In [160]: list(prepare([1,3]))
Out[160]: [1, False, 3]

In [161]: list(prepare([1,3,5]))
Out[161]: [1, False, 3, False, 5]
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Beitragvon klaus » Sonntag 20. Juli 2008, 13:46

Also ehrlichgesagt finde ich meine Lösung jetzt nicht unübersichtlich. Sie ist vielleicht nicht elegant, aber jetzt auch nicht komplett konfus. Sie wird vielleicht dadurch etwas lang, dass ich allein 3 Zeilen brauche um den IndexError abzufangen, der beim letzten Schleifendurchlauf entsteht.

Außerdem muss ich sagen, dass ich noch nicht sehr gut im Umgang mit Python bin und mit dem reservierten Wort "yield" noch nicht gearbeitet habe. Ich kann deine Lösung also leider nicht ganz nachvollziehen, aber ich werde sie mir mal genauer anschauen.
BlackJack

Beitragvon BlackJack » Sonntag 20. Juli 2008, 14:27

Also ich fand die Lösung so konfus, dass ich sie mir gar nicht richtig angeschaut hatte. Habe ich jetzt nachgeholt und da sprang mich Zeile 5 an: Dir ist klar, das `index()` die Liste wieder von vorne nach dem Element durchsucht, das wir längst "in Händen halten"? Damit hat die Funktion quadratische Laufzeit in Abhängigkeit der Länge der Liste. Zähl den Index besser mit `enumerate()` gleich in der Schleife mit.

Und was sollen die beiden Zeilen 3 und 4? Den Effekt, den die haben, hast Du in der Anforderung nicht beschrieben.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Beitragvon klaus » Sonntag 20. Juli 2008, 14:52

Ok, den index mitzählen ist möglich, dann muss ich nochmal schauen, wie ich es dann schreibe.
Ohne Zeile 3 und 4 erhalte ich eine Funktion, die nach der ersten Lücke unendlich oft False einfügt. Daher muss ich prüfen ob ich schon ein False eingefügt habe und dann weitergehen.

edit:Ich glaube ich habe jetzt so ungefähr das Prinzip verstanden, wie man mit yield arbeitet. Allerdings weiß ich noch nicht genau, wohin es die Werte zurückgibt. Meine Vermutung ist, dass es genau wie return funktioniert, mit dem einzigen Unterschied, dass es die Funktion nicht beendet und daher beliebig viele Werte zurückgeben kann, die man das mit list() in eine Liste umwandeln und einer Variablen zuweisen kann.

So wie es scheint habe ich es jetzt auch geschafft, die Funktion so zu ergänzen, dass sie mehrfach vorhandene Werte automatisch beseitigt. bis jetzt habe ich das "von Hand" vorgenommen indem ich die liste mit set() in eine Menge umgewandelt habe und dann wieder zurück. In der Funktion muss ich dafür nur eine extra-Abfrage einfügen (Zeile 6 und 7), was wahrscheinlich weniger Rechenleistung in Anspruch nimmt. Meine fertige Funktion sieht dann so aus:

Code: Alles auswählen

def prep(x):
    x.sort()
    x = iter(x)
    a = x.next()
    for b in x:
        if a == b:
            continue
        yield a
        if b - a > 1:
            yield False
        a = b
    yield a
BlackJack

Beitragvon BlackJack » Sonntag 20. Juli 2008, 16:17

Zu den Zeilen 3 und 4 in Deiner vorherigen Lösung: Ah, dann hatte ich immer noch nicht so ganz verstanden wie's geht. Ich wollte auf die "Sonderbehandlung" von der 0 hinaus:

Code: Alles auswählen

In [28]: prepare([1,3])
Out[28]: [1, False, 3]

In [29]: prepare([0,2])
Out[29]: [0, 2]


Ich weiss nicht, ob Dir diese kleine Anomalie bewusst war/ist.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Beitragvon klaus » Sonntag 20. Juli 2008, 19:19

Die Anomalie ist mir nicht aufgefallen, allerdings ist sie für mich auch nicht weiter schlimm, da ich eine Codezeile vor dieser Funktion alle Zahlen < 0 aus der Liste lösche.
BlackJack

Beitragvon BlackJack » Sonntag 20. Juli 2008, 19:56

Bei < 0 kann der Bug noch zuschlagen, ich denke Du meinst <= 0!? :-)
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Beitragvon klaus » Sonntag 20. Juli 2008, 19:58

eig. meinte ich <1 ;)
Allerdings würde es mich trotzdem interessieren, wodurch der bug entsteht.
BlackJack

Beitragvon BlackJack » Sonntag 20. Juli 2008, 20:03

0 ist "falsch":

Code: Alles auswählen

In [50]: bool(0)
Out[50]: False

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder