Seite 1 von 1

Evolution eines Python-Programmierers - Listen

Verfasst: Dienstag 13. Dezember 2011, 13:03
von /me
Gegeben sei folgende Datenstruktur.

Code: Alles auswählen

data = [[(23, 'Alpha'), (42, 'Bravo')], [(11, 'Charlie')], [(12, 'Delta'), (13, 'Echo')]]
Darin abgebildet sind User mit ID und Name die jeweils einer Gruppe zugeordnet sind. Es soll eine Funktion geschrieben werden, die alle IDs als Liste zurückgibt.


Der von einer anderen Programmiersprache kommende Newbie löst das so:

Code: Alles auswählen

def get_ids_newbie(data):
    ids = []
    for i in range(len(data)):
        for j in range(len(data[ i])):
            element = data[ i][j]
            ids.append(element[0])
    return ids
Mit etwas mehr Erfahrung und vorherigem Studium des Tutorials wird die Lösung pythonischer:

Code: Alles auswählen

def get_ids_beginner(data):
    ids = []
    for group in data:
        for element in group:
            ids.append(element[0])
    return ids
Nachdem man Python endlich verstanden hat ergibt sich dann:

Code: Alles auswählen

def get_ids_advanced(data):
    ids = [element[0] for group in data for element in group]
    return ids
Und irgendwann kennt man dann auch die Standardbibliothek:

Code: Alles auswählen

from itertools import chain
def get_ids_profi(data):
    return [element[0] for element in chain(*data)]
Eine Alternative wäre chain.from_iterable(data).

Gefährlich wird es nur, wenn man in der Standardbibliothek andere Dinge findet und die als geeignet ansieht:

Code: Alles auswählen

import re
def get_ids_braindamaged(data):
    return eval('[' + re.sub(r'[^\d,]+,?', '', repr(data)) + ']')
Ja, das funktioniert - und bricht dann mit anderen Daten plötzlich zusammen. Nicht nachmachen!

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 00:02
von derdon
/me hat geschrieben:Und irgendwann kennt man dann auch die Standardbibliothek:

Code: Alles auswählen

from itertools import chain
def get_ids_profi(data):
    return [element[0] for element in chain(*data)]
Eine Alternative wäre chain.from_iterable(data).
Das geht noch viel cooler mit operator.itemgetter :P

Code: Alles auswählen

In [51]: from itertools import chain

In [52]: from operator import itemgetter

In [53]: def get_ids_profi(data):
   ....:     return map(itemgetter(0), chain.from_iterable(data))
   ....: 

In [54]: get_ids_profi(data)
Out[54]: [23, 42, 11, 12, 13]

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 00:30
von lunar
@derdon: Bin ich jetzt uncool, wenn ich die LC cooler finde? ;)

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 01:06
von Leonidas
Die LC ist sicherlich pythonischer, richtig. Als Lisp-Weenie find ich aber `itemgetter` "cooler" (wobei OK, Clojure hat auch LCs).

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 09:29
von snafu
Es kommt immer auf die Nanosekunden an Geschwindigkeitsvorsprung an. 8)

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 09:34
von EyDu
Oder für diesen Spezialfall:

Code: Alles auswählen

dict(itertools.chain(*data)).keys()

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 11:45
von sma
Ich präferiere die reine LC, weil ich einen Ansatz, der kein "import" benötigt, immer besser finde. Ohne "import" ist es für mich die Sprache selbst, die ihre Ausdrucksstärke demonstriert, mit "import" ist es einfach nur die Funktionsbibliothek.

Stefan

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 12:01
von snafu
sma hat geschrieben:Ich präferiere die reine LC, weil ich einen Ansatz, der kein "import" benötigt, immer besser finde. Ohne "import" ist es für mich die Sprache selbst, die ihre Ausdrucksstärke demonstriert, mit "import" ist es einfach nur die Funktionsbibliothek.
Warst *du* etwa dieser Troll von letztens...? :twisted:

Re: Evolution eines Python-Programmierers - Listen

Verfasst: Mittwoch 14. Dezember 2011, 13:10
von cofi
Neee, den haben wir doch schon lange .. wobei sma auch schon lange da ist .. :twisted:

Er hat aber einen guten Punkt: Wenn man andere Klassen nutzt, ist das auch in Java ein Einzeiler. Oder in ASM (naja mit Stack vorbereiten vllt doch ein paar mehr ;))