7

I have a nested list a = [1, 2, [3, 4], 5] and I want to apply a function that will raise every number to the power of 2. The result will be like this:

a = [1, 4, [9, 16], 25]

I tried a = [list(map(lambda x : x * x, x)) for x in a] but it gives this error

'int' object is not iterable

How we can fix this issue? How can I apply a function over a nested list?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Ash
  • 79
  • 1
  • 4
  • You are trying to `apply` your function to each outer list item, but some of them are lists (ok to apply) and the others are numbers (not ok to apply). – DYZ Dec 22 '18 at 21:21
  • You can flatten your irregular list and then apply lambda. Below is the duplicate link on how to flatten – Sheldore Dec 22 '18 at 21:21
  • Possible duplicate of [Flatten an irregular list of lists](https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists) – Sheldore Dec 22 '18 at 21:21

2 Answers2

9

You probably need a recursive function that distinguishes between lists and scalars:

def square(item):
    if isinstance(item, list):
        return [square(x) for x in item]
    else:
        return item * item

square(a)
#[1, 4, [9, 16], 25]

Incidentally, this approach works for arbitrary-nested lists.

Here's a more general solution:

def apply(item, fun):
    if isinstance(item, list):
        return [apply(x, fun) for x in item]
    else:
        return fun(item)

apply(a, lambda x: x * x)
#[1, 4, [9, 16], 25]
DYZ
  • 55,249
  • 10
  • 64
  • 93
  • 1
    completely unrelated, but your `apply` looks like a ["functor"](https://wiki.haskell.org/Functor), interesting how/where these things turn up! – Sam Mason Dec 22 '18 at 22:36
3

You are decomposing your list into its elements -some of them are lists which can not be multiplied with itself ([3,4]*[3,4]).

Not sure if that is smart - but you can use a "recursing" lambda:

a =[1, 2, [3, 4], 5]

l = lambda x : x * x if isinstance(x,int) else list(map(l,x))
a = list(map(l, a))

print(a)

Output:

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

Works also for "deeper" levels:

a =[1, 2, [3, [7,8], 4], 5]

Output:

[1, 4, [9, [49, 64], 16], 25]

but will crash if you mix non-iterables things into the mix

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69