0

Is there a way in Python to let the len(x) function (or any similar function) return 1 if x is a simple float?

In my case, I have x as a input parameter to a function, and I want to make it robust to (NumPy) array type inputs of x as well as simple scalar float input of x. In the function, the len(x) function is used, but it throws an error object of type 'float' has no len() if x is a float, whereas I want it to return 1. Of course I can write an if statement, but I feel like there should be a shorter solution.

def myfunc(x):
    y=np.zeros((5,len(x)))
    y[1,:]=x
    ....
    return y
Xander
  • 5,487
  • 14
  • 49
  • 77
  • 2
    Write your own function `mylen()` that does what you want, and then call it instead of `len()`. – John Gordon Feb 05 '20 at 19:33
  • Can you show some sample code where `len` is the only thing that stops you from using a float as if it's a sequence? It's hard to guess what use-case you have where your code works with both floats and arrays, except for needing to do `len`. – kaya3 Feb 05 '20 at 19:33
  • 3
    Can't you simply `return 1 if type(x) == float else len(x)`? – accdias Feb 05 '20 at 19:33
  • 2
    What does your function do that makes sense for both scalar and array values? I'd bet it would make more sense to simply disallow a single `float` value, or require the caller to pass a singleton list. – chepner Feb 05 '20 at 19:39
  • Of course I could easily include a simple function like that, I just thought there should be a standard way of doing it since Python is designed so robust against using functions for both scalar and vector inputs – Xander Feb 05 '20 at 19:45
  • Yes, based on the edit I think you should just write an `if` statement or ternary expression here, if you do want the function to work with a single `float` value. It seems like not a common enough situation that it would be worth having a helper function for, but if you need to do it a lot, write a helper function. There isn't anything built-in like `len` that does what you want. By the way, `isinstance(x, float)` is preferable to `type(x) == float`. – kaya3 Feb 05 '20 at 19:47
  • @kaya3 Thank you for your perspective on this! – Xander Feb 05 '20 at 19:50
  • "since Python is designed so robust against using functions for both scalar and vector inputs" not really. Most built in functions will throw a type error for this sort of thing. Maybe you are thinking of numpy? – juanpa.arrivillaga Feb 05 '20 at 20:32
  • @juanpa.arrivillaga Indeed, I was referring to numpy (sorry for unclarity). Is there a numpy alternative for `len()` that works also on float type? – Xander Feb 09 '20 at 10:31

1 Answers1

0

No, there is no built-in function like this.

One of the core aspects of how Python is designed is that it is strongly typed, meaning that values are not implicitly coerced from one type to another. For example, you cannot do 'foo' + 3 to make a string 'foo3'; you have to write 'foo' + str(3) to explicitly convert the int to str in order to use string concatenation. So having built-in operators or functions which could treat a scalar value as if it's a sequence of length 1 would violate the principle of strong typing.

This is in contrast with weakly typed languages like Javascript and PHP, where type coercion is done with the idea that the programmer doesn't have to think so much about data types and how they are converted; in practice, if you write in these languages then you still do have to think about types and conversions, you just have to also know which conversions are or aren't done implicitly.

So, in Python if you want a function to work with multiple different data types, then you either have to do a conversion explicitly (e.g. if isinstance(x, float): x = np.array([x])) or you have to only use operations which are supported by every data type your function accepts (i.e. duck typing).

kaya3
  • 47,440
  • 4
  • 68
  • 97