Seite 1 von 2
Mississippi
Verfasst: Freitag 6. November 2009, 19:18
von hendrikS
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)]
Verfasst: Freitag 6. November 2009, 19:27
von rayo
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.
Verfasst: Freitag 6. November 2009, 19:31
von gerold
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.
Verfasst: Freitag 6. November 2009, 19:34
von ms4py
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.
Verfasst: Freitag 6. November 2009, 19:51
von Defnull
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']
Verfasst: Freitag 6. November 2009, 20:35
von gerold
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!
Verfasst: Freitag 6. November 2009, 20:56
von hendrikS
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.
Verfasst: Freitag 6. November 2009, 21:18
von pillmuncher
Ä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]])
Verfasst: Freitag 6. November 2009, 22:36
von gerold
Hallo!
Nur mal kurz darüber nachgedacht...
Wir amüsieren uns hier köstlich mit diesen Quellcode-Abschnitten!
Aber stellt euch mal vor, ihr zeigt diesen Thread euren Freunden/Eltern/Verwanden...
Was sind wir wohl in deren Augen?
lg
Gerold
Verfasst: Freitag 6. November 2009, 22:41
von numerix
gerold hat geschrieben:Wir amüsieren uns hier köstlich mit diesen Quellcode-Abschnitten!
Aber stellt euch mal vor, ihr zeigt diesen Thread euren Freunden/Eltern/Verwanden...
Was sind wir wohl in deren Augen?
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 ...
Verfasst: Freitag 6. November 2009, 22:45
von pillmuncher
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)
Verfasst: Freitag 6. November 2009, 22:56
von pillmuncher
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.
Gruß,
Mick.
Verfasst: Freitag 6. November 2009, 23:01
von gerold
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
Verfasst: Freitag 6. November 2009, 23:03
von Leonidas
gerold hat geschrieben:Wir amüsieren uns hier köstlich mit diesen Quellcode-Abschnitten!
Aber stellt euch mal vor, ihr zeigt diesen Thread euren Freunden/Eltern/Verwanden...
Was sind wir wohl in deren Augen?
Wenn wir schon blödeln, dann steuere ich eine
Scheme-Lösung bei. Wäre gespannt was man mit Factor zaubern könnte
Verfasst: Freitag 6. November 2009, 23:12
von gerold
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
Verfasst: Freitag 6. November 2009, 23:33
von hendrikS
gerold hat geschrieben:
Was sind wir wohl in deren Augen?
Bestimmt nicht so schlimm wie Du denkst. Jeder hat so seinen Spleen.
Scheme:
Die vielen Klammern haben mich immer davon abgehalten das mal zu probieren.
Und nicht zuletzt:
Gerolds nonmagic Version ist die effizienteste der Varianten.
Verfasst: Samstag 7. November 2009, 00:46
von pillmuncher
Leonidas hat geschrieben:Wenn wir schon blödeln, dann steuere ich eine
Scheme-Lösung bei. Wäre gespannt was man mit Factor zaubern könnte
Factor kann ich nicht, aber Prolog:
Code: Alles auswählen
group(String, Groups) :-
string_to_list(String, [C|Cs]),
group(Cs, [C], Groups).
group([C|Cs], [C|Group], Groups) :-
!,
group(Cs, [C,C|Group], Groups).
group([C|Cs], Group, [String|Groups]) :-
group(Cs, [C], Groups),
string_to_list(String, Group).
group([], Group, [String]) :-
string_to_list(String, Group).
Code: Alles auswählen
?- group("mississippi",G).
G = ["m", "i", "ss", "i", "ss", "i", "pp", "i"].
Da sieht man auch, wo ich das
def _group(s, *ss): herhab
Verfasst: Montag 9. November 2009, 08:46
von ms4py
Hab meine Lösung nochmal überarbeitet^^
Code: Alles auswählen
from itertools import tee, izip
def group(s):
a, b = tee(s)
output = list()
output.append(b.next())
for prev_char, char in izip(a, b):
if prev_char == char:
output[-1] += char
else:
output.append(char)
return output
Prolog weckt düstere Erinnerungen... Konnte das noch nie leiden
Verfasst: Montag 9. November 2009, 16:14
von pillmuncher
ice2k3 hat geschrieben:Code: Alles auswählen
a, b = tee(s)
output = list()
output.append(b.next())
Das
b.next() ist eine gute Idee:
Code: Alles auswählen
def group(cs):
cs = iter(cs)
s = cs.next()
for c in cs:
if c in s:
s += c
else:
yield s
s = c
yield s
ice2k3 hat geschrieben:Prolog weckt düstere Erinnerungen... Konnte das noch nie leiden
Juhuu! Ein Sprachenkrieg
Ich mochte Prolog schon immer, hatte auch nie irgendwelche Verständnis-Probleme (anders als bei Haskell
). Irgendwie scheint es der Verdrahtung meines Gehirns zu entsprechen. Und von Differenzlisten hab ich schon geträumt:
Code: Alles auswählen
?- asserta(append_dl(A - B, B - C, A - C)).
true.
?- append_dl([1,2,3|X] - X, [4,5,6|Y] - Y, Z - []).
X = [4, 5, 6],
Y = [],
Z = [1, 2, 3, 4, 5, 6] .
Gruß,
Mick.
Verfasst: Montag 9. November 2009, 21:50
von Nocta
Fehlt nicht noch was rekursives?
Code: Alles auswählen
def group(s, res=[], i=0, j=1):
if i >= len(s)-1:
return res + [s[i]*j]
if s[i] == s[i+1]:
return group(s, res, i+1, j+1)
else:
return group(s, res + [s[i]*j], i+1)
Das würde ich zwar nicht als elegant bezeichnen aber darum poste ich's weil mir gerade kein guter rekursiver Weg einfällt und irgendjemand hier soll ihn mir offenbaren
(Ist zwar fast schon peinlich, aber ich bin hier ja anonym :p)