Python odds and ends scope, filter, reduce

description code comments 
quickly assign values a,b,c = (3,7,12)  unpack
nested functions outer func return inner func

Python's built-in scope

  • check out Python's built-in scope, which is really just a built-in module called builtins
  • to query builtins, you'll need to import builtins
In [16]:
import builtins
print dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__builtins__', '__doc__', '__file__', '__future_module__', '__name__', '__package__', '__path__', 'abs', 'absolute_import', 'all', 'any', 'apply', 'ascii', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'dreload', 'enumerate', 'eval', 'execfile', 'file', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'sys', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

nested functions

  • return innter function
In [22]:
def raise_val(n):
    
    """Return the inner function."""
    def inner(x):
        """Raise x to the power of n."""
        raised = x ** n
        return raised
    
    return inner
In [25]:
square = raise_val(2)
cube =  raise_val(3)

print square(6), cube(6)
36 216

pass parameters

In [30]:
raise_val(4)(3)
Out[30]:
81

scope searched

  • Local scope
  • Enclosing functions
  • Global
  • Built-in
In [44]:
n=3

def outer():
    """Prints the value of n."""
    n = 1
    def inner():
        n = 2
        print(n)
        
    inner()
    print(n)
In [45]:
outer()
2
1

nested func

  • nesting functions is the idea of a closure
  • This means that the nested or inner function remembers the state of its enclosing scope when called
  • Thus, anything defined locally in the enclosing scope is available to the inner function even when the outer function has finished execution
In [46]:
# Define echo
def echo(n):
    """Return the inner_echo function."""

    # Define inner_echo
    def inner_echo(word1):
        """Concatenate n copies of word1."""
        echo_word = word1 * n
        return echo_word

    # Return inner_echo
    return inner_echo

# Call echo: twice
twice = echo(2)

# Call echo: thrice
thrice = echo(3)

# Call twice() and thrice() then print
print(twice('hello'), thrice('hello'))
('hellohello', 'hellohellohello')
In [48]:
echo(7)('wtf ')
Out[48]:
'wtf wtf wtf wtf wtf wtf wtf '

flexible arguments

Function with variable-length arguments (*args)

In [51]:
# Define gibberish
def gibberish(*notmatter):
    """Concatenate strings in *args together."""

    # Initialize an empty string: hodgepodge
    hodgepodge = ''

    # Concatenate the strings in args
    for word in notmatter:
        hodgepodge += word+ ' '

    # Return hodgepodge
    return hodgepodge

# Call gibberish() with one string: one_word
one_word = gibberish("luke")

# Call gibberish() with five strings: many_words
many_words = gibberish("luke", "leia", "han", "obi", "darth")

# Print one_word and many_words
print(one_word)
print(many_words)
luke 
luke leia han obi darth 

Function with variable-length keyword arguments (**kwargs)

In [55]:
# Define report_status
def report_status(**whatevername):
    """Print out the status of a movie character."""

    print("\nBEGIN: REPORT\n")

    print whatevername
    print 
    # Print a formatted status report
    for key, value in whatevername.items():
        print(key + ": " + value)

    print("\nEND REPORT")

# First call to report_status()
report_status(name="luke", affiliation="jedi", status="missing")

# Second call to report_status()
report_status(name="anakin", affiliation="sith lord", status="deceased")
BEGIN: REPORT

{'status': 'missing', 'affiliation': 'jedi', 'name': 'luke'}

status: missing
affiliation: jedi
name: luke

END REPORT

BEGIN: REPORT

{'status': 'deceased', 'affiliation': 'sith lord', 'name': 'anakin'}

status: deceased
affiliation: sith lord
name: anakin

END REPORT

Map() and lambda functions

In [56]:
# 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)

# Convert shout_spells into a list and print it
print(shout_spells_list)
['protego!!!', 'accio!!!', 'expecto patronum!!!', 'legilimens!!!']

Filter() and lambda functions

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

  • filter(function or None, sequence) -> list, tuple, or string

  • Return those items of sequence for which function(item) is true. If function is None, return the items that are true. If sequence is a tuple or string, return the same type, else return a list.

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

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


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

# Convert result into a list and print it
print(result_list)
['samwise', 'aragorn', 'legolas', 'boromir']
In [69]:
filter(lambda member: len(member) >3, ['1234','234','34567'])
Out[69]:
['1234', '34567']
In [83]:
filter(None, [12>1, 'wtf' if 2>1 else 0, 'aiya' if 3>2 else 7, 'momomo' if 4>5 else -44])
Out[83]:
[True, 'wtf', 'aiya', -44]

Reduce() and lambda functions

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.

  • reduce(function, sequence[, initial]) -> value
  • Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value.
  • For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5).
  • If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
In [86]:
# Import reduce from functools
from functools import reduce

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

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

# Print the result
print(result)
robb sansa arya eddard jon

error handling

  • raise error
In [88]:
try: '3'+3
except Exception, e: print e
cannot concatenate 'str' and 'int' objects
In [91]:
# Define shout_echo
def shout_echo(word1, echo=1):
    """Concatenate echo copies of word1 and three
    exclamation marks at the end of the string."""

    # Raise an error with raise
    if echo < 0:
        raise ValueError('echo must be greater than 0')

    # Concatenate echo copies of word1 using *: echo_word
    echo_word = word1 * echo

    # Concatenate '!!!' to echo_word: shout_word
    shout_word = echo_word + '!!!'

    # Return shout_word
    return shout_word

# Call shout_echo
try:
    shout_echo("particle", echo=-3)
except Exception, e: 
    print e
echo must be greater than 0
In [96]:
shout_echo("123", echo=-1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-96-44c64dc8c830> in <module>()
----> 1 shout_echo("123", echo=-1)

<ipython-input-91-d6d66ed4753d> in shout_echo(word1, echo)
      6     # Raise an error with raise
      7     if echo < 0:
----> 8         raise ValueError('echo must be greater than 0')
      9 
     10     # Concatenate echo copies of word1 using *: echo_word

ValueError: echo must be greater than 0

use filter(lambda: x ...) in Pandas

In [98]:
# Select retweets from the Twitter dataframe: result

result = filter(lambda x: x[0:2] == 'RT', df['text'])
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-98-ac4d1cb6d465> in <module>()
      1 # Select retweets from the Twitter dataframe: result
      2 
----> 3 result = filter(lambda x: x[0:2] == 'RT', df['text'])

NameError: name 'df' is not defined
In [ ]: