1

I want to input a two-dimensional array into a python function, by hand.

For example:

x = numpy.zeroes(1,2)
x[0,0] = 2
x[0,1] = 4
def f(x):
    return x**2
f(x)

This function returns an array with elements 4 and 16. However, I want to be able to input the two-dimensional element to the function by hand such as f(2,4), f([2,4]) but they don't work.

1
  • 3
    f(numpy.array([2, 4])) Commented Jun 21, 2016 at 1:06

1 Answer 1

3

The reason why inputting f(2, 4) and f([2, 4]) does not work because, for the former, the function only accepts one argument and, for the latter, you are passing in a Python list.

Numpy arrays have more functionality. Python lists do not. You can see the difference when you look at their class methods:

>>> x = numpy.array([[2.0, 4.0]])
>>> dir(x)
['T', '__abs__', '__add__', '__and__', '__array__', '__array_finalize__', '__array_interface__', '__array_prepare__', '__array_priority__', '__array_struct__', '__array_wrap__', '__class__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__delslice__', '__div__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__', '__idiv__', '__ifloordiv__', '__ilshift__', '__imod__', '__imul__', '__index__', '__init__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__setslice__', '__setstate__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'all', 'any', 'argmax', 'argmin', 'argpartition', 'argsort', 'astype', 'base', 'byteswap', 'choose', 'clip', 'compress', 'conj', 'conjugate', 'copy', 'ctypes', 'cumprod', 'cumsum', 'data', 'diagonal', 'dot', 'dtype', 'dump', 'dumps', 'fill', 'flags', 'flat', 'flatten', 'getfield', 'imag', 'item', 'itemset', 'itemsize', 'max', 'mean', 'min', 'nbytes', 'ndim', 'newbyteorder', 'nonzero', 'partition', 'prod', 'ptp', 'put', 'ravel', 'real', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'setfield', 'setflags', 'shape', 'size', 'sort', 'squeeze', 'std', 'strides', 'sum', 'swapaxes', 'take', 'tobytes', 'tofile', 'tolist', 'tostring', 'trace', 'transpose', 'var', 'view']
>>> x = [2.0, 4.0]
>>> dir(x)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

Notice that the numpy array has a __pow__ method but the Python list does not. This is a special method that allows you to dictate how Python would use the ** function on the array. Therefore, the numpy array can be squared.

>>> x = [1, 2, 3]
>>> x**2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'

There are a few ways to go about this problem. You can either pass in a numpy array as Headcrab has said or make your function more complex. I will explain how to make a function that fits all three cases.

To deal with all three cases, you will have to check what the type of the data passed in is and you will have to accept multiple arguments.

def f(x, *args):
    if args:
        # If there are multiple arguments e.g. f(2, 4)
        return [x**2] + [n**2 for n in args]
    elif isinstance(x, list):
        # If a Python list is passed e.g. f([2, 4])
        return [n**2 for n in x]
    else:
        # If something else (probably numpy array) is passed e.g. f(numpy.array([2, 4]))
        return x**2

Some test cases:

>>> f(1, 2)
[1, 4]
>>> f(2, 4)
[4, 16]
>>> f(3, 6)
[9, 36]

.

>>> f([1, 2])
[1, 4]
>>> f([2, 4])
[4, 16]
>>> f([3, 6])
[9, 36]

.

>>> f(numpy.array([1, 2]))
array([1, 4])
>>> f(numpy.arry([2, 4]))
array([ 4, 16])
>>> f(numpy.array([3, 6]))
array([ 9, 36])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.