There is a quicker way to write functions: lambdas !

raise_to_power = lambda x, y: x ** y
raise_to_power(2, 3)

-> 8

So basically you specify the variables in input, and then the operation which is performed et.. voila !

You can also write anonymous functions :

Function map takes two arguments: map(func, seq)

map() applies the function to ALL elements in the sequence

nums = [48, 6, 9, 21, 1]
square_all = map(lambda num: num ** 2, nums)
print(square_all)
-><map object at 0x103e065c0>
print(list(square_all))
-> [2304, 36, 81, 441, 1]

Some small exercises :

# Define echo_word as a lambda function: echo_word
echo_word = (lambda word1,echo:word1*echo)

# Call echo_word: result
result = echo_word('hey',5)

# Print result
print(result)

->heyheyheyheyheyhey

Lambda function with map()

The best use case for lambda functions, however, are for when you want these simple functionalities to be anonymously embedded within larger expressions. What that means is that the functionality is not stored in the environment, unlike a function defined with def. To understand this idea better, you will use a lambda function in the context of the map() function.

Recall from the video that map() applies a function over an object, such as a list. 

# Create a list of strings: spells
spells = ["protego", "accio", "expecto patronum", "legilimens"]

# Use map() to apply a lambda function over spells: shout_spells
shout_spells = map(lambda item:item+'!!!',spells)

# Convert shout_spells to a list: shout_spells_list
shout_spells_list=list(shout_spells)

# Print the result
print(shout_spells_list)

->
['protego!!!', 'accio!!!', 'expecto patronum!!!', 'legilimens!!!']

Lambda function with filter ()

The function filter() offers a way to filter out elements from a list that don’t satisfy certain criteria.

# Create a list of strings: fellowship
fellowship = ['frodo', 'samwise', 'merry', 'pippin', 'aragorn', 'boromir', 'legolas', 'gimli', 'gandalf']

# Use filter() to apply a lambda function over fellowship: result
result = filter(lambda item : len(item)>6, fellowship)

# Convert result to a list: result_list
result_list=list(result)

# Print result_list
print(result_list)

->
['samwise', 'aragorn', 'boromir', 'legolas', 'gandalf']

Lambda function with reduce()

The reduce() function is useful for performing some computation on a list and, unlike map() and filter(), returns a single value as a result. To use reduce(), you must import it from the functools module.

# Import reduce from functools
from functools import reduce # only in Python 3

# Create a list of strings: stark
stark = ['robb', 'sansa', 'arya', 'brandon', 'rickon']

# Use reduce() to apply a lambda function over stark: result
result = reduce(lambda item1,item2: item1+item2, stark)

# Print the result
print(result)

->
robbsansaaryabrandonrickon

Introduction to error handling

Sometimes you will get errors while trying to do things that are not permitted in Python :

float(2)
-> 2.0

float('hello')
->

ValueError Traceback (most recent call last)
<ipython-input-3-d0ce8bccc8b2> in <module>()
<hr />-> 1 float('hi')
ValueError: could not convert string to float: 'hello'

If you have a function that returns the square root of something then you cannot pass strings as arguments.

def sqrt(x):
"""Returns the square root of a number."""
    return x ** (0.5)
sqrt(4)

sqrt(10)
->3.1622776601683795

sqrt('hello')
->
TypeError Traceback (most recent call last)
<ipython-input-4-cfb99c64761f> in <module>()
----> 1 sqrt('hello')
<ipython-input-1-939b1a60b413> in sqrt(x)
1 def sqrt(x):
----> 2 return x**(0.5)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'float'

How to deal with errors and exceptions :

Catch exceptions with try-except clause

  • Runs the code following try
  • If there’s an exception, run the code following except
def sqrt(x):
"""Returns the square root of a number."""
    try:
        return x ** 0.5
    except:
        print('x must be an int or float')
sqrt(4)
-> 2
sqrt('yo')
-> x must be an int or float

You can also raise problems :

def sqrt(x):
    """Returns the square root of a number."""
    if x < 0:
        raise ValueError('x must be non-negative')
    try:
        return x ** 0.5
    except TypeError:
        print('x must be an int or float')

Indeed the square root of a negative number does not make much sense

Now, bringing it all together while using once again the twitter feed : o select retweets, that is, tweets that begin with the string 'RT'

# Select retweets from the Twitter DataFrame: result
result = filter(lambda x:x[0:2]=='RT' , tweets_df['text'])

# Create list from filter object result: res_list
res_list=list(result)

# Print all retweets in res_list
for tweet in res_list:
    print(tweet)

Now we take back the code from last time and add a try/except in case the column specified by the user is not in the list of columns of the data frame:

# Define count_entries()
def count_entries(df, col_name='lang'):
    """Return a dictionary with counts of
    occurrences as value for each key."""

    # Initialize an empty dictionary: cols_count
    cols_count = {}

    # Add try block
    try:
        # Extract column from DataFrame: col
        col = df[col_name]
        
        # Iterate over the column in dataframe
        for entry in col:
    
            # If entry is in cols_count, add 1
            if entry in cols_count.keys():
                cols_count[entry] += 1
            # Else add the entry to cols_count, set the value to 1
            else:
                cols_count[entry] = 1
    
        # Return the cols_count dictionary
        return cols_count

    # Add except block
    except:
        Print('The DataFrame does not have a ' + col_name + ' column.')

# Call count_entries(): result1
result1 = count_entries(tweets_df, 'lang')

# Print result1
print(result1)

And finally we also do it using a raise statement :

# Define count_entries()
def count_entries(df, col_name='lang'):
    """Return a dictionary with counts of
    occurrences as value for each key."""
    
    # Raise a ValueError if col_name is NOT in DataFrame
    if col_name not in df.columns:
        raise ValueError('The DataFrame does not have a ' + col_name + ' column.')

    # Initialize an empty dictionary: cols_count
    cols_count = {}
    
    # Extract column from DataFrame: col
    col = df[col_name]
    
    # Iterate over the column in DataFrame
    for entry in col:

        # If entry is in cols_count, add 1
        if entry in cols_count.keys():
            cols_count[entry] += 1
            # Else add the entry to cols_count, set the value to 1
        else:
            cols_count[entry] = 1
        
        # Return the cols_count dictionary
    return cols_count

# Call count_entries(): result1
result1=count_entries(tweets_df,'lang')

# Print result1
print(result1)