Home > Net >  python lambda map over nested list
python lambda map over nested list

Time:03-22

I recently received the following question in a Hackerrank that I wasn't able to answer and I haven't found the correct answer anywhere else.

Complete the lambda map function: given a array such as [[1,2,3,-1,2],[2,4,-3]] take the square of all the non-negative numbers in the two arrays. The output is suppose to be:

[1,4,9,4]

[4,16]

Additionally, the array will also contain an additional number at the beginning of the array which is the length of the array. So in the above example, the length is 2 so the final array that will be passed through the function will be [2, [1,2,3,-1,2],[2,4,-3]]. (We don't want to take the square of the initial number, in this case 2)

def lambdamap(arr):

    final = map(

 #write your lambda function here

 , arr)
    
return final

create a lambda function within the map that creates the desired output.

I have tried a number of different ways such as

map(lambda x: x**2, filter(lambda x: x>0, arr)) 

But this does not work on nested lists like the array that is passed through the function. Please let me know if there is any information I can provide to help clarify the question.

CodePudding user response:

While I'm not certain of this, it sounds like the input might have the length included in the beginning and it needs to be passed through untouched. If that's the case, here's a single lambda function that will take the input and produce the desired output:

lambda i: [n**2 for n in i if n > 0] if isinstance(i, list) else i

This portion does the squaring on the non-negatives: [n**2 for n in i if n > 0]

But only if the value is a list: if isinstance(i, list)

Otherwise pass the value through: else i

That means this input [2, [1, 2, 3, -1, 2], [2, 4, -3]] returns this output [2, [1, 4, 9, 4], [4, 16]]

CodePudding user response:

You have to use a lambda function within a lambda function. The result isn't that pretty, but it works:

list(map(lambda x: list(map(lambda y: y ** 2, filter(lambda z: z > 0, x))), arr[1:]))

With the given input case, this outputs:

[[1, 4, 9, 4], [4, 16]]

If you can't use list slicing, you could use filter(lambda x: isinstance(x, list), arr) rather than arr[1:].


Let's start at the innermost lambda functions and work our way outwards. To simplify things, we start by considering how to perform this operation on a single list, called x:

  • filter(lambda z: z > 0, x) gives us all the positive elements in x.
  • We then square all of these elements using map: map(lambda y: y ** 2, ...)
  • This gives us map(lambda y: y ** 2, filter(lambda z: z > 0, x)).

This gives us something that works for a single list. How do we extend it to work with a list of lists? Well, the operation is defined in the same way for each list, so use map again! (slicing off the first element because it isn't a list, and transforming the map objects into lists to match the desired output).

This finally gives us:

list(map(lambda x: list(map(lambda y: y ** 2, filter(lambda z: z > 0, x))), arr[1:]))

as specified originally.

CodePudding user response:

def lambdamap(arr):
    return map(
        lambda x: map(
            lambda y: y**2,
            filter(lambda z: z > 0, x)
        ),
        map(
            lambda b: b[1],
            filter(lambda a: a[0] > 0, enumerate(lst))
        )
    )

For better readability we can also do:

def lambdamap(arr):
    _arr = map(
        lambda b: b[1],
        filter(lambda a: a[0] > 0, enumerate(lst))
    )

    return map(
        lambda x: map(lambda y: y**2, filter(lambda z: z > 0, x)),
        _arr
    )
lst = [2, [1, 2, 3, -1, 2], [2, 4, -3]]


outcome = [list(x) for x in list(lambdamap(lst))]
print(outcome)
  • Related