2016-07-05 6 views
1

Ich schreibe eine Funktion, die eine Liste von Zahlen durchläuft und eine Liste der Summen der Teiler jeder Zahl zurückgibt. Ich versuche, meine Funktion ein wenig zu trimmen und gleichzeitig map(lambda..)10 zu lernen.Ungültige Syntax, wenn versucht wird, (Lambda ..)

def DoWork(nums): 
    sums = [] 
    for n in nums: 
     divisors = [] 
     map(lambda i: divisors.append(i) if not (n%i), range(1,n+1)) 
     sums.append(sum(divisors)) 
    return sums 

Ich erhalte einen Syntaxfehler aber in Bezug auf die ersten , in der map() Linie.

+0

Lambda-Funktionen sind nicht wie in C++, wo man tatsächlich Variablen erfassen kann ... –

+0

Was soll 'Lambda i: divisors.append (i) wenn nicht (n% i)' bedeuten? – bereal

Antwort

2

Normalerweise verwenden wir map() in Situationen, in denen wir eine Abfolge von Dingen [1] haben und sie in eine andere Sequenz von gleicher Länge transformieren wollen, indem wir auf jedes Element eine Funktion anwenden.

Sie können es immer noch verwenden, um die Summe der Teiler zu finden, aber ich würde argumentieren, dass es nicht das am besten geeignete Werkzeug dafür ist.

Lassen Sie mich Ihnen stattdessen zeigen, wie wir map und lambda auf Ihr Problem anwenden können, indem Sie es aus einem etwas anderen Blickwinkel betrachten.

Zunächst einmal lassen Sie uns Ihre Funktion neu schreiben eine Liste Verständnis zu verwenden:

def DoWork(nums): 
    sums = [] 
    for n in nums: 
     divisors = [i for i in range(1, n+1) if not n % i] 
     sums.append(sum(divisors)) 
    return sums 

nun beobachten, dass die divisors Liste nicht erforderlich ist und beseitigt werden:

def DoWork(nums): 
    sums = [] 
    for n in nums: 
     sums.append(sum(i for i in range(1, n+1) if not n % i)) 
    return sums 

Jetzt können wir leicht die Transformation gesamte Funktion in einem einzigen Anruf zu map():

def DoWork(nums): 
    return map(lambda n: sum(i for i in range(1, n+1) if not n % i), nums) 

[1] map() kann auch verwendet werden, um mehrere Sequenzen - im Allgemeinen von gleicher Länge - in eine einzelne Sequenz zu transformieren, indem die gleiche Funktion wiederholt auf die Eingabesequenzen angewendet wird.

2

Ein Python lambda funktioniert nicht so. Es sollte ein einfacher Ersatz für eine Funktion sein, die einen Wert annimmt und einen anderen Wert zurückgibt. Sie können keine if Bedingungen haben, die darin schweben.

updated_range = filter(lambda x: not n%x, range(1,n+1)) 
map(lambda i: divisors.appens(i), updated_range) 
#The above code is a bad style. See below! 

Hinweis: In der Regel lambdas nicht ändert einen externen Zustand. Es ist ein schlechter Stil divisors.append(..)

Verbesserte Version # 1 zu nennen:

updated_range = filter(lambda x: not n%x, range(1,n+1)) 
map(lambda i: divisors.append(i), updated_range) 

Verbesserte Version # 2 (die Lambda-Fixierung, die keinen externen Zustand nicht ändern):

updated_range = filter(lambda x: not n%x, range(1,n+1)) 
divisors = map(lambda i: i, updated_range) 
#(lambda i: i) is an identity function: returns whatever we give it. 
#Sort of useless, though. 

Verbesserte Version # 3 (Mehr pythonic!):

divisors = [x for x in range(1, n+1) if not n%x] 
+0

... und unter Berücksichtigung, dass "Lambda i: i" nichts tut, ist die letzte Zeile auch redundant. – bereal

+0

Ja, ich weiß, das war für das OP, einem Gedankengang zu folgen. – SuperSaiyan

+0

'Sie können nicht haben, wenn Bedingungen darin schweben. - Können Sie @Buffalo Rabors Antwort erklären, warum diese Behauptung? – MrDuk

1

Der Syntaxfehler steigt von unvollständiger 'wenn nicht' Logik, wo eine 'else' Klausel erforderlich ist.

def DoWork(nums): 
    sums = [] 
    for n in nums: 
     divisors = [] 
     map(lambda i: divisors.append(i) if not (n%i) else 1, range(1,n+1)) 
     sums.append(sum(divisors)) 
    return sums 

fehlerfreie Ausführung ...

DoWork(range(0,10)) 
[0, 1, 3, 4, 7, 6, 12, 8, 15, 13]