2017-05-29 4 views
0

Ich bin nicht in der Lage, meine Meinung über die Funktion map(). Ich habe Code von einem example genommen. Ich würde gerne wissen, was genau in dieser Codezeile passiert.Welche Informationen werden in einem Python-Map-Objekt gespeichert?

labels = map(itemgetter(1),map(os.path.split,map(os.path.dirname,labels))) 

Die Werte von Etiketten vor dieser Aussage ist

<class 'list'>: ['classify-test/aligned/clapton/clapton-1.png', 'classify-test/aligned/clapton/clapton-2.png', 'classify-test/aligned/lennon/lennon-1.png', 'classify-test/aligned/lennon/lennon-2.png'] 

Ich weiß, dass wenn ich map(os.path.split,map(os.path.dirname, labels[0])) habe ich clapton den Wert bekommen würde.

Aber kann ich eine andere Logik verwenden, um diese Karte zu konvertieren. Und was ist der Rückgabetyp der labels=map(itemgetter(1),map(os.path.split,map(os.path.dirname,labels))) Linie.

Ist es eine Liste von Strings oder etwas anderes?

Antwort

3

Nehmen Sie die folgende pure-Python-Implementierung von map:

def my_map (func, iterable): 
    for item in iterable: 
     yield func(item) 

Dies ist im Wesentlichen war die eingebaute in map den Fall ist, nur in nativen Code, so dass es viel schneller ist.

Also map wird nur die Funktion als erstes Argument an jedes einzelne Element der iterablen übergeben übergeben als das zweite Argument anwenden. In Ihrem Fall zu verstehen, was passiert, sollten Sie die Linie von innen nach außen lesen:

map(itemgetter(1), map(os.path.split, map(os.path.dirname, labels))) 
                  ^^^^^^ 
               Start here: This is your iterable 

              ^^^^^^^^^^^^^^^ 
              Run os.path.dirname(x) on every element x 

         ^^^^^^^^^^^^^ 
         Run os.path.split(y) on every element y of the previous result 

    ^^^^^^^^^^^^^ 
    Run itemgetter(1)(z) on every element z of the previous result 

Da Sie map dreimal ausgeführt wird, können Sie drei Funktionen auf dem ursprünglichen Element anwenden. Sie könnten diese Funktionen kombinieren, um es klar etwas zu machen:

def getDirectoryName(label): 
    return os.path.split(os.path.dirname(label))[1] 

result = map(getDirectoryName, labels) 

jene Funktion Anrufe richtig macht dies schon viel klarer gekettet, die uns leicht erraten können, was die kombinierte Funktion macht: In diesem Fall ist es ruft das Verzeichnis des übergebenen Labels ab (welches ein Pfad ist) und teilt es dann auf, um nur den Namen des Verzeichnisses zu erhalten. Man könnte hier auch os.path.basename verwenden anstatt den Pfad manuell zu teilen.

Da dies so viel klarer ist, ist dies der Grund, warum Sie selten map in Python-Code verwendet werden. Die oft bevorzugte Weg wäre, eine Liste Verständnis zu verwenden:

result = [os.path.split(os.path.dirname(label))[1] for label in labels] 

Hier haben Sie den Vorteil der beiden: Alles in prägnanter Weise, aber dennoch einfach zu verstehen, da es anstelle funktionaler Imperativ Code.

+0

Vielen Dank das Lesen und Verstehen viel einfacher zu machen :) –

Verwandte Themen