Consider having a list of objects defined like this:
class MyItem:
    def __init__(self):
        self.count = 0
    def increase(self):
        self.count += 1
    def decrease(self):
        self.count -=1
    def get_count(self):
        return self.count
all_objects = []
for i in range(10):
    all_objects.append(MyItem())
At various points in the program, the methods increase and decrease are called. Now you want to find the item which has the biggest count, but the max function doesn't know the details of your object's implementation. Therefore, you need to let it know which function to use to evaluate the items between themself. In this case, this would be the item's get_count method, and you would call the max like this:
max(all_objects, key=lambda x: x.get_count)
Basically, a key is the "reasoner" for the sorting, a value that is used for comparison.  
To understand it better, consider that every call to a list of integers like this:
some_list = [1,2,3]
max(some_list)  # returns 3
is the same as providing it a key as an unmodified value:
some_list = [1,2,3]
max(some_list, key=lambda x:x)
Update
Author has asked: 
Could i incorporate booleans into the key element?
so I am extending my answer with the reply.
In short, the answer is: yes. But in practice, this has little to no use. As for explanation, consider the following case:
my_list = [True, False, False, True, False, False, False]
max(my_list)
The result will obviously be True, since it is convention that True>False. But the question is, which True object is returned (remember that everything is an object in Python, even boolean types)? Is it the first one or the second one? Well, that depends on the internal implementation of ṁax. Since this is so, we don't have practical use of this application. (Incidentally, max is implemented to return the first one, but this doesn't concern us at this time.)  
Important note:   The above example is a simplification that assumes that two True object are in fact two different object, which is not correct. In reality
  they are the same object in Python, as noted by @mu無 in the comments. Consider this as a lumpy 
  example, and for a more relevant one, read on.
But lets check how this behaves with our previous example:  
class MyItem:
    def __init__(self, id):
        self.count = 0
        self._bool = bool(random.randrange(2))
        self.id = id
    def increase(self):
        self.count += 1
    def decrease(self):
        self.count -=1
    def get_count(self):
        return self.count
    def get_bool(self):
        return self._bool
We have added only three things, the id to identify the object, the private attribute _bool and the getter function get_bool to be used as the key. Lets create a list of such objects and do some random incrementing to differentiate between them:
import random
all_objects = []
for i in range(10):
    new_obj = MyItem(i)
    for k in range(random.randrange(10)):
        new_obj.increase()
    all_objects.append(new_obj)
At this point, we have a list all_objects containing 10 MyItem objects with random values in their count attribute, and a random boolean value in their _bool attribute.
Now lets see what happens when we try to sort that. We will first print all of them, so its easier to make a conclusion. I will show three consecutive results as columns to preserve space.
# a helper function to print formatted output  
def print_object(obj):
    print "id: {0} count: {1} _bool: {2}".format(o.id, o.get_count(), o.get_bool())
# print all objects followed by delimited line
# for the object returned by max
for o in all_objects: print_object(o)
print "-"*27
max_obj = max(all_objects, key=lambda x:x.get_bool())
print_object(max_obj)
The output:
id: 0 count: 1 _bool: False     id: 0 count: 2 _bool: False     id: 0 count: 1 _bool: False
id: 1 count: 7 _bool: True      id: 1 count: 3 _bool: False     id: 1 count: 4 _bool: False
id: 2 count: 0 _bool: False     id: 2 count: 1 _bool: False     id: 2 count: 2 _bool: False    
id: 3 count: 5 _bool: False     id: 3 count: 4 _bool: False     id: 3 count: 1 _bool: True
id: 4 count: 4 _bool: False     id: 4 count: 6 _bool: False     id: 4 count: 9 _bool: False
id: 5 count: 4 _bool: False     id: 5 count: 6 _bool: False     id: 5 count: 3 _bool: False
id: 6 count: 7 _bool: True      id: 6 count: 4 _bool: False     id: 6 count: 5 _bool: False
id: 7 count: 8 _bool: True      id: 7 count: 7 _bool: True      id: 7 count: 1 _bool: True
id: 8 count: 1 _bool: True      id: 8 count: 8 _bool: False     id: 8 count: 9 _bool: False
id: 9 count: 7 _bool: True      id: 9 count: 4 _bool: False     id: 9 count: 1 _bool: False
---------------------------     ---------------------------     ---------------------------
id: 1 count: 7 _bool: True      id: 7 count: 7 _bool: True      id: 3 count: 1 _bool: True
From the output we can clearly see that the function returned the first item with the _bool attribute containing the value True. Which is hardly max of anything important...