[Python-de] 1,2,3,5,7,8,9 -> "1-3,5,7-9"

René Liebscher R.Liebscher at gmx.de
Mon Jun 21 09:23:39 CEST 2004


kgm schrieb:
> Hi,
> 
> On Fri, 18 Jun 2004 10:54:39 +0200, René Liebscher <R.Liebscher at gmx.de>  
> wrote:
> 
>> Wie das von der Laufzeit bei sehr grossen Eingabelisten aussieht, ist
> 
> 
> habe Deine Laufzeit-Anmerkung mal zum Anlass genommen, einige der  
> geposteten Varianten zu messen. Hier die Messung für 30000 Zahlen:
> 
> Anzahl 30000
> Laufzeit (Frank): 7.6432 sec
> Laufzeit (kgm): 3.1479 sec
> Laufzeit (Jan): 6.8867 sec
> Laufzeit (Rene): 122.2487 sec
> 
> 
Also wenn Du schon mal mit Laufzeitmessungen anfängst solltest Du, dann 
aber auch meinen Hinweis auf die schlechte Laufzeit beachten und die 
andere Lösung nehmen (die zuerst gepostete mit Generator).
Dann kommt ungefähr folgendes raus (Python 2.2 mit einen mehr schlechten 
als rechten Nachbau von random.sample)

Anzahl 30000
Laufzeit (Frank): 7.3800 sec
Laufzeit (kgm): 1.8900 sec
Laufzeit (Jan): 4.5400 sec
Laufzeit (Rene): 62.5200 sec
Laufzeit (Rene,y2): 0.2900 sec
Laufzeit (Rene,x): 0.2300 sec


x ist die Lösung mit Generator.
y2 die mit reduce aber mit Veränderung der übergebenen Liste. (Es 
existiert also nur noch eine Liste und nicht bei jedem Funktionsaufruf 
eine neue.)
##############################################
def y2(list,element):
     if len(list) == 0:
         return [element]
     # Nachfolger von letzem in der liste
     if list[-1] == element-1:
         # liste erst angefangen oder irgendwas wie '... , x' drin
         if len(list)<2 or list[-2]==',':
             # anhaengen
             list.append('-')
             list.append(element)
             return list
         else:
             # letztes Element in Liste austauschen
             list[-1]=element
             return list
     else:
         # neues anhaengen
         list.append(',')
         list.append(element)
         return list
##############################################

So gesehen gefällt mir das Ergebnis viel besser, weil meine erste Lösung 
  dann doch schon die schnellste war ;-)
Man müsste das zwar nochmal gegen die anderen Verbesserungen 
vergleichen, aber die Lösung mit Generator halte ich irgendwie immer 
noch für die übersichtlichste. Zumal ich da auch jedes Listenelement nur 
einmal zugreifen muss, könnte der Input selbst wieder ein 
Iterator/Generator oder irgendeine andere nichtwiederholbare Sequenz 
sein. (Dann muss natürlich die for-Anweisung ersetzt werden.)
Die zweite Sache mit dem nachträglichen Umwandeln in einen String (mit 
str/join) halte ich eher für einen Vorteil, weil man hinterher noch die 
einzelnen Elemente da hat, falls man die nochmal braucht. (Sonst ist 
String parsen angesagt.)

MfG
Rene


PS: Mehr Kommentare im Quelltext bei den anderen Beiträgen wären schon 
sinnvoll gewesen, gerade wenn man versucht anderen die Funktionsweise 
der eigenen Lösung nahezubringen.