Function that is agnostic to object implementing len() or shape

Viewed 52

I have a function func(x) which expects a parameter x. x should be some kind of collection or array. func(x) needs to get the length of x:

 def func(x):        
    for i in range(len(x)):
        print('Something', i)

The problem is that some collection-like objects have len() implemented but not .shape (e.g. a list) others have .shape implemented but not len() (e.g. a sparse matrix). What is the most pythonic way to make func(x) work, regardless of this issue? Or are there other things to consider when looking for a solution for this problem?

What I can think of:

  • Expecting another parameter: func(x, length_of_x)

  • Calling a different function altogether

  • Catching missing implementation with try-except:

     import numpy as np
     from scipy.sparse import csr_matrix
     def func(x):
         try:
             length_of_x = len(x)
         except:
             length_of_x = x.shape[0]
    
         for i in range(length_of_x):
             print('Something', i)
    
     func([1, 2, 3])
    
     sparse_matrix = csr_matrix(([1, 2, 3, 4, 5, 6], ([0, 0, 1, 2, 2, 2], [0, 2, 2, 0, 1, 2])))
     func(sparse_matrix)
    
  • if-else Block

     def func(x):
         if isinstance(x, csr_matrix):
             length_of_x = x.shape[0]
         else:
             length_of_x = len(x)   
         for i in range(length_of_x):
             print('Something', i)
    
1 Answers

The most Pythonic way to approach would be to build the internal logic using iterators rather than indexes.

def func(x):        
    for value in x:
        print('Something', value)
Related