Apply function to list regardless of levels in python

Hi,

I found this answer by @Konrad_K_Sobon on SO about how to make a python script handle different list structures, but for some reason it’s not working on a different function and I can’t figure out why. I guess it’s the unwrapping that’s causing problems.

I’m getting AttributeError: ‘List[object]’ object has no attribute ‘ViewType’. It’s not supposed to call the passed function on the object if it’s a list, but it seems it’s not recognizing this unwrapped List[object]. How can I get around this?

import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

views = UnwrapElement(IN[0])

def ProcessList(_func, _list):
    return map( lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list )
    
def getViewType(view):
	return view.ViewType

if isinstance (views, list):
    outlist = ProcessList(getViewType, views)
else:
    outlist = getViewType(views)

OUT = outlist

How about handling any list structure:

#Function to handle any list structure
ProcessLists = lambda function, lists: [ProcessLists(function, item) if isinstance(item, list) else function(item) for item in lists]
ApplyFunction = lambda func, objs: ProcessLists(func, objs) if isinstance(objs, list) else [func(objs)]

#Funtion to unwrap
def Unwrap(item):
    return UnwrapElement(item)
    
#Preparing input from dynamo to revit 
if isinstance(IN[0], list):
	views = ProcessLists(Unwrap, IN[0])
else:
	views = Unwrap(IN[0])

#Define function to get view type
def getViewType(view):
	return view.ViewType

#OUTPUT
OUT = ApplyFunction(getViewType,views)
6 Likes

That definitely has a much better ring to it :smile: and you didn’t fail to deliver

Thanks Kulkul! Could you maybe let me know why we need the
ApplyFunction = lambda func, objs: ProcessLists(func, objs) if isinstance(objs, list) else [func(objs)]
line here? I’m still trying to wrap my head around how it all actually works.

This would be good start for you:

1 Like

Oh I did learn about lambdas just a few days ago, but I couldn’t figure out how exactly you’re using it in this case. I guess I’ll just have to dissect your code more closely to understand when I have some time.