Mississippi

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Freitag 6. November 2009, 19:18

In Haskell gibt es eine Funktion group, mit folgendem Effekt:
"Mississippi" => ['M', 'i', 'ss', 'i', 'ss', 'i', 'pp', 'i']
Habs mal in py nachgebaut. Vielleicht kanns jemand gebrauchen. Interessieren würde mich, ob man das auch mit einer Regexp schaffen kann. Habs versucht. Leider ohne Erfolg.

Code: Alles auswählen

def group(s):
    o = list()
    t = list(s[0])
    for c in s[1:]:
        if c == t[0]:
            t.append(c)
        else:
            o.append(''.join(t))
            t = list(c)
    return o + [''.join(t)]
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Freitag 6. November 2009, 19:27

Hi

Das kannst du auch mit itertools.groupby lösen:

Code: Alles auswählen

import itertools

s = "Mississippi"
print list(key*len(list(group)) for key,group in itertools.groupby(s))
Gruss

*edit* Gerolds Lösung ist definitiv schöner ... so weit hab ich wieder mal nicht gedacht.
Zuletzt geändert von rayo am Freitag 6. November 2009, 19:47, insgesamt 1-mal geändert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 6. November 2009, 19:31

Hallo!

Ich mag solche Ein-/Zweizeiler eigentlich nicht, aber ausnahmsweise... :-)

Code: Alles auswählen

>>> import itertools
>>> [ "".join(value) for key, value in itertools.groupby("Mississippi") ]
['M', 'i', 'ss', 'i', 'ss', 'i', 'pp', 'i']
>>>

mfg
Gerold
:-)


Edit: Ohhh, zu spät. ;-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Freitag 6. November 2009, 19:34

Hier eine Lösung mit ``itertools``, die nicht ganz so magisch ist:

Code: Alles auswählen

from itertools import tee, izip
def group2(s):
    a, b = tee(s)
    b.next()
    o = [s[0]]
    i = 0
    for a0, b1 in izip(a, b):
        if a0 == b1:
            o[i] += b1
        else:
            o.append(b1)
            i += 1
    return o
Geht aber bestimmt noch besser.

Edit: OK, geht deutlich besser ^^
Als LC find ich das am besten, das mit list und * ist das auch nicht so elegant.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Freitag 6. November 2009, 19:51

Jup, das geht auch mit re

Code: Alles auswählen

>>> [m[0] for m in re.findall('((?P<char>.)(?P=char)*)','Mississippi')]
['M', 'i', 'ss', 'i', 'ss', 'i', 'pp', 'i']
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 6. November 2009, 20:35

Ich habe noch einen... diesmal ganz ohne Magie. :-) Ziemlich ähnlich der Lösung von hendrikS.

Code: Alles auswählen

dest_list = []
prev_char = None
for char in "Mississippi":
    if char == prev_char:
        dest_list[-1] += char
    else:
        dest_list.append(char)
    prev_char = char
print dest_list
lg
Gerold
:-)

PS: @Defnull: Tolle Lösung! 8)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Freitag 6. November 2009, 20:56

wow. Jede menge Alternativlösungen.
Wenn ich gewußt hätte, daß es groupby gibt, hätte ichs vielleicht auch so gemacht.
Zur RegexpLösung. Erst habe ich gedacht, daß ist uneffizient. Beim zweiten Hinsehen finde ich es doch ziemlich smart.
Benutzeravatar
pillmuncher
User
Beiträge: 1138
Registriert: Samstag 21. März 2009, 22:59
Wohnort: München

Freitag 6. November 2009, 21:18

Ähnlich wie Gerolds Lösung:

Code: Alles auswählen

def group(cs):
    def groups(a, b):
        if b in a[-1]:
            a[-1] += b
        else:
            a += b
        return a
    return reduce(groups, cs[1:], [cs[:1]])
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 6. November 2009, 22:36

Hallo!

Nur mal kurz darüber nachgedacht...

Wir amüsieren uns hier köstlich mit diesen Quellcode-Abschnitten! :D
Aber stellt euch mal vor, ihr zeigt diesen Thread euren Freunden/Eltern/Verwanden...
Was sind wir wohl in deren Augen? :mrgreen:

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Freitag 6. November 2009, 22:41

gerold hat geschrieben:Wir amüsieren uns hier köstlich mit diesen Quellcode-Abschnitten! :D
Aber stellt euch mal vor, ihr zeigt diesen Thread euren Freunden/Eltern/Verwanden...
Was sind wir wohl in deren Augen? :mrgreen:
So etwas KANN man nicht zeigen, wenn man es im "echten Leben" auch mit "normalen" Menschen zu tun hat. Ansonsten setzt man sich der Gefahr einer Zwangseinweisung aus ...
Benutzeravatar
pillmuncher
User
Beiträge: 1138
Registriert: Samstag 21. März 2009, 22:59
Wohnort: München

Freitag 6. November 2009, 22:45

Noch einer, diesmal lazy:

Code: Alles auswählen

def _group(s, *ss):
    for c in ss:
        if c in s:
            s += c
        else:
            yield s
            s = c
    yield s

def group(cs):
    if cs == '':
        return iter('')
    return _group(*cs)
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
pillmuncher
User
Beiträge: 1138
Registriert: Samstag 21. März 2009, 22:59
Wohnort: München

Freitag 6. November 2009, 22:56

numerix hat geschrieben:So etwas KANN man nicht zeigen, wenn man es im "echten Leben" auch mit "normalen" Menschen zu tun hat. Ansonsten setzt man sich der Gefahr einer Zwangseinweisung aus ...
Ich fand es immer schon ziemlich punkig, ein Nerd zu sein. :twisted:

Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 6. November 2009, 23:01

pillmuncher hat geschrieben:Noch einer, diesmal lazy:

Code: Alles auswählen

def _group(s, *ss):
    ...
def group(cs):
    ...
    return _group(*cs)
Hallo!

Dieses Beispiel nehmen wir jetzt um Python-Anfängern die Übergabe von Parametern zu erklären. ;-)

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 6. November 2009, 23:03

gerold hat geschrieben:Wir amüsieren uns hier köstlich mit diesen Quellcode-Abschnitten! :D
Aber stellt euch mal vor, ihr zeigt diesen Thread euren Freunden/Eltern/Verwanden...
Was sind wir wohl in deren Augen? :mrgreen:
Wenn wir schon blödeln, dann steuere ich eine Scheme-Lösung bei. Wäre gespannt was man mit Factor zaubern könnte :)
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 6. November 2009, 23:12

Hallo!

Weiß jemand, wie das in Cython http://www.cython.org/ aussehen könnte? Ich interessiere mich dafür, da ich vielleicht demnächst ein paar Codeteile (nicht zwischenspeicherbare Rabattberechnungen) meines Onlineshops hoch optimieren muss.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten