Bessere Implementierung möglich?

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.
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Bessere Implementierung möglich?

Beitragvon apollo13 » Dienstag 17. Juli 2007, 16:25

Wenn ja bitte mit ganz kurzer Erklärung :)

Der Code:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def slice_it(my_list, columns=2):
    """slice_it(my_list, columns=2): Gibt eine Liste, die `columns` Listen
    enthält zurück. Jede dieser Listen repräsentiert eine Spalte, wie sie
    in Zeitungen/Wörterbüchern zu finden sind.
    >>> slice_it(range(10))
    [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
    >>> slice_it(range(10),3)
    [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]
    >>> slice_it(range(10),4)
    [[0, 1, 2], [3, 4, 5], [6, 7], [8, 9]]
    """
    length = len(my_list)
    mod = length % columns
    step = length/columns
    pos = 0
    new_list = []
    i = 0
    while i < columns:
        if mod != 0:
            new_pos = pos+step+1
            new_list.append(my_list[pos:new_pos])
            pos = new_pos
            mod -= 1
        else:
            new_pos = pos+step
            new_list.append(my_list[pos:new_pos])
            pos = new_pos
        i += 1
    return new_list

if __name__ == "__main__":
    import doctest
    doctest.testmod()
    print "Tests done."


Thx, apollo13[/code]
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Dienstag 17. Juli 2007, 17:42

Was meinst du mit besser? Ich habe es lediglich etwas kürzer:

Ganz kurz und grausam:

Code: Alles auswählen

def slice_it(li, cols=2):
   lengths = [len(li[i::cols]) for i in range(cols)]
   return [li[sum(lengths[:i]):sum(lengths[:i])+lengths[i]] for i in range(cols)]


Besser lesbar durch eine for-Schleife:

Code: Alles auswählen

def slice_it(li, cols=2):
   lengths = [len(li[i::cols]) for i in range(cols)]
   result = []
   for i in range(cols):
      start = sum(lengths[:i])
      stop = start + lengths[i]
      result.append(li[start:stop])
   return result


Und natürlich noch als Generator-Funktion:

Code: Alles auswählen

def slice_it(li, cols=2):
   lengths = [len(li[i::cols]) for i in range(cols)]
   for i in range(cols):
      start = sum(lengths[:i])
      stop = start + lengths[i]
      yield li[start:stop]


Edit: Da ist mir noch was schöneres eingefallen:

Code: Alles auswählen

def slice_it(li, cols=2):
    start = 0
    for i in range(cols):
        stop = start + len(li[i::cols])
        yield li[start:stop]
        start = stop
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Beitragvon apollo13 » Dienstag 17. Juli 2007, 18:02

Wow, thx :)
lunar

Beitragvon lunar » Dienstag 17. Juli 2007, 18:29

Du solltest xrange verwenden, solange du nicht wirklich eine Liste mit Zahlenwerten benötigst.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Dienstag 17. Juli 2007, 18:36

Erinnert mich an http://genshi.edgewall.org/wiki/HelperFunctions

Kürzeste Variante da:

Code: Alles auswählen

def group(iterable, num):
    """Group an iterable into an n-tuples iterable. Incomplete tuples
    are discarded e.g.
   
    >>> list(group(range(10), 3))
    [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
    """
    return map(None, *[iter(iterable)] * num)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Dienstag 17. Juli 2007, 18:42

Ouh, das ist aber ziemlich gewagt...
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Dienstag 17. Juli 2007, 19:29

lunar hat geschrieben:Du solltest xrange verwenden, solange du nicht wirklich eine Liste mit Zahlenwerten benötigst.

Meine Code ist halt schon Python-3000-kompatibel :D
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Beitragvon apollo13 » Dienstag 17. Juli 2007, 22:20

lunar hat geschrieben:Du solltest xrange verwenden, solange du nicht wirklich eine Liste mit Zahlenwerten benötigst.

Du meinst wegen dem Geschwindigkeitsvorteil?

Y0Gi hat geschrieben:Erinnert mich an http://genshi.edgewall.org/wiki/HelperFunctions
Kürzeste Variante da: ...

Hmm ich weiß aber die Nummer nicht, ich will die Columns angeben. Trotzdem interessantes Beispiel, danke. Ich glaub ich muss mir map mal genau anschauen...

birkenfeld hat geschrieben:Ouh, das ist aber ziemlich gewagt...
Was ist gewagt und warum?

EyDu hat geschrieben:Meine Code ist halt schon Python-3000-kompatibel :D
Wieso, gibt es dann kein xrange mehr?

Thx, apollo13
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Beitragvon veers » Dienstag 17. Juli 2007, 22:49

apollo13 hat geschrieben:Wieso, gibt es dann kein xrange mehr?
Weil sich range dann wie xrange verhalten wird. ;)
lunar

Beitragvon lunar » Mittwoch 18. Juli 2007, 09:00

apollo13 hat geschrieben:
lunar hat geschrieben:Du solltest xrange verwenden, solange du nicht wirklich eine Liste mit Zahlenwerten benötigst.

Du meinst wegen dem Geschwindigkeitsvorteil?

Und Speicherverbrauch!

Code: Alles auswählen

for i in range(1000000):
     print i


Dieser Code erzeugt erst eine Liste mit einer Million Elementen im Speicher, bevor die Iteration beginnt, und hält diese Liste noch dazu die ganze Zeit im Speicher, obwohl die vorherigen Elemente nicht gebraucht werden.

Und was Python-3000 angeht: Ich wünsche mir jetzt schon happy porting ;)

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder