简体   繁体   中英

Invalid syntax when trying to map(lambda..)

I'm writing a function that loops through a list of numbers, and returns a list of the sums of each number's divisors. I'm trying to trim my function down a little, and learn map(lambda..) at the same time.

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

I'm getting a syntax error though, regarding the first , in the map() line.

A python lambda does not work that way. It is should be a simple substitute for a function that takes a value and returns another value. You can not have if conditions floating in it.

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!

Note : Typically, lambdas do not modify an external state. It is considered a bad style to call divisors.append(..)

Improved version #1:

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

Improved version #2 (fixing the lambda that doesn't modify external state):

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.

Improved version #3 (More pythonic!):

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

Typically, we use map() in situations where we have a sequence of things [1] and want to transform it into another sequence -- of the same length -- by applying a function to each element.

You can still use it to find the sum of divisors, but I would argue that it's not the most suitable tool for that.

Instead, let me show you how we can apply map and lambda to your problem by looking at it from a slightly different angle.

First of all, let's rewrite your function to use a list comprehension:

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

Now observe that the divisors list is unnecessary and can eliminated:

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

Now we can easily transform the entire function into a single call to map() :

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

[1] map() can also be used to transform multiple sequences -- generally of the same length -- into a single sequence by applying the same function repeatedly across the input sequences.

The syntax error is rising from incomplete 'if not' logic, where an 'else' clause is required.

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

error free execution...

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM