Parentheses ‘()’ after Function Names

I understand the modifier being “.lower” or “.upper”, etc. but what is the logic of the “()” after them?

Under what circumstance would something be within the parenthesis?

upper() and lower() are methods (bound functions) of the str class.
When you call a function, the parentheses contain the parameters
you’re passing to it. Invoking the name of a function without the
parentheses refers to the object for the function rather than
executing it. You can see this in the REPL:

>>> 'FOO'.lower()
'foo'
>>> 'FOO'.lower
<built-in method lower of str object at 0x7f0c87dc1bf0>

The lower() method happens to take no arguments, but there are
plenty of other methods of str which do, for example:

>>> 'FOO'.strip('F')
'OO'

Just an example where you can use the str.lower() method without the parenthesis:

>>> words = ['I', 'BUMPED', 'INTO', 'CAPS', 'LOCK']
>>> list(map(str.lower, words))
['i', 'bumped', 'into', 'caps', 'lock']

Here you are not directly calling the function/method but you are giving the function as an argument to the function map().

These variants have the same result, they use the same method, but they differ in the way you give the argument to the function:

>>> 'CAPS'.lower()
'caps'
>>> str.lower('CAPS')
'caps'

A function is a block of code which only runs when it is called.

You can pass data, known as parameters, into a function.

A function can return data as a result.


Creating a Function

In Python a function is defined using the def keyword:

Example

def my_function():
print(“Hello from a function”)


Calling a Function

To call a function, use the function name followed by parenthesis:

Example

def my_function():
print(“Hello from a function”)

my_function()

So this is what W3schools tells me a function is and that it needs to be defined by “def”…

My logic brain says a function is any “thing” that has a defined set of parameters and data. For example a variable defined by an = and data would also be a function since it can be called by an action.

I imagine the only difference is that the “def” function cannot be changed from it’s original content and therefore is better for repeatitious “calls” through a program.

I’m still trying to find what “map()” does it’s not on my list of methods besides format.map()

You can imagine a function as a block of code which can receive its input data as arguments, which can return data and which you can call. In Python everything is an object so functions are objects too.

Any variable is not a function (or a callable) because a variable in general does not define how to behave when called.[1]

You cannot (easily) change an existing function but you can certainly bind a different function to an existing name:

def greeting():
    print('Hello')

def greeting():  # This binds a new function to the existing name greeting
    print('Hi')

def greeting3():
    print('Good morning')

greeting = greeting3  # assignment like for any other variable
# again binds a different function to the existing name

# You can even create a function using an expression (without def):
greeting = lambda: print('Bye')
# Do not use this in production code to create named functions, there are some important differences.

map(function, iterable) processes the iterable (like list, tuple, str…) by processing every its item using the provided function. The result is an iterable (more specifically an iterator) of the processed items (return values of function).

list(map(function, [1, 2]))
# gives the same result as:
[function(1), function(2)]

https://docs.python.org/3/library/functions.html#map


  1. this is done by implementing the __call__() method ↩︎

I should be sleeping right now, so I’m going to make this short:

I’m pretty sure that I read recently at docs.python.org that list comprehension is preferable to map(). It even sounded a bit like map() might be on its way to becoming deprecated, but that could have just been my impression.

I didn’t find the reference when I searched just now, but the duplication is mentioned in Functional Programming HOWTO and here’s an external link to a good comparison of the two.

Yes, in Python generator expression or list comprehension is preferred over map(). I used map just as a simple example where you can pass str.lower as a parameter. …but maybe sorted([...], key=str.lower) would have been a better example. …not sure which one is simpler for a beginner.

Hi Brad,

No, assignment is not a function.

x = 1  # This is not a function.

In Python, assignment is a statement.

The Python programming language has a few distinct kinds of code, which can be divided into two fundamental groups: statements and expressions.

A “statement” is a single Python command. Some of them are one-liners:

import math  # load the `math` module and allow it to be used

Some require a block of code following them:

for x in ['one', 'two', 'three']:
    # block of code follows here
    print(x)

An expression is a special kind of statement that has a value. Values can be numbers, strings, lists and more complex things:

1 + 2  # has the value 3
"Hello world"
[1+2, "Hello", "Goodbye"]  # A list.

Notice that expressions can contain other expressions.

Assignment or “name-binding” is a statement:

value = 1 + 2

(although there is also an expression form of that, but don’t worry about that for now).

When we say the word “function”, we can mean it in two senses. In the first sense, we mean a special kind of value:

  • Numbers are things that you can perform arithmetic on;
  • Strings are things that can hold words and sentences etc;
  • Lists are containers that can hold other things inside them;

and functions are things that contain code which you run by calling the function, optionally by passing arguments to it.

So in that sense, a function is a thing. Like other things, you can put functions inside lists, you can print them, you can assign them to a variable, delete them, etc.

By the way, in Python we call things “objects”.

The other sense of “function” is a statement that *creates a function object:

def myfunction(arg):
    # block of code goes here.
    return ["Hello", arg, 999]

This def statement:

  1. creates a function object;
  2. and assigns it to the variable “myfunction”.

Now that you have a function (sense 1) assigned to a variable, you can do anything you like to it:

print(myfunction)

That will print something like

<function myfunction at 0x7fbeae3dcdc0>

In this case we are treating the function object, a thing, as a value: we want to print the value. The print out is not very exciting. It tells us that it is a function, its name, and a unique location in memory which is almost totally useless.

If we want to treat the function object as a function, we need to call it by putting round brackets (parentheses) after it, and supplying any necessary arguments.

myfunction(2.5)

That is an expression, so it produces a value which we can assign to a variable, or print, or whatever needed:

var = myfunction(2.5)
print(var)  # Prints the list ["Hello", 2.5, 999]

Can functions be changed? Sort of.

Technically, yes, function objects can be disassembled, like a car engine, and put back together with bits replaced or removed or added, but that’s not common or easy to do.

In practice, 99% of the time we create functions with the def statement, and then just call them, nothing more.

3 Likes

To understand map(), we have to understand the idea of higher order functions, which comes from the functional programming paradigm.

We learn about plain old ordinary functions from maths at school. A function takes a value, say, a number, and processes it somehow, returning (say) a new number:

pow(5, 2)  # Returns 25

In my previous post, I talked about the fact that in Python, functions themselves are values, just like strings and numbers and lists. So what if we wrote a function which expected to receive another function as an argument? Or a function that took in some values as arguments and returned a new function.

These would be called higher order functions, and the technique can be used to automate the creation of functions. Here is a basic example:

def adder_factory(value):
    def inner(num):
       return value + num
   return inner

plus_one = adder_factory(1)
plus_two = adder_factory(2)
plus_hundred = adder_factory(100)

Can you guess what the functions plus_one, plus_two and plus_hundred do? Try them and see if you are right.

This brings us back to map(). This is a standard, simple, higher order function which takes as argument another function, and a list of values, then calls that input argument with each of the values in the list.

lengths = list(map(len, ['aaa', 'bb', 'c', 'dddd']))
print(lengths)

Can you guess what that does? Try it and see.

This is the essence of a function and Functional Programming: Provide inputs and only receive an output.

And it might be helpful to illustrate that adder_factory creates functions with…

print(plus_one(10))
  or
a = plus_one(10)
print(a)
  or even
print(plus_one()) since you mentioned using print() to show that a function is an object.

Parantheses ‘()’ are the most important part within the function. Whenever any value has to be pass within the function in order to make it known inside the entire function, the arguments pass through these paranthesis. However, the parentheses can also be empty.