Get Odds

def get_all_odds(numbers):
    odds=filter(lambda x:x%2, numbers)
    odd_list=list(odds)
    return odd_list

def has_odds(numbers):
    odds = get_all_odds(numbers)
    at_least_one_odd = len(odds) > 0
    if at_least_one_odd:
        return True
    else:
        return False

if __name__ == "__main__":
    assert get_all_odds([1, 2, 3, 4, 5, -2, -1]) == [1, 3, 5, -1]
    assert has_odds([0, 2, 5]) is True
    assert has_odds([0, 2, 4]) is False
  1. No reason to do list on separate line after filter: “Simple is better than complex.”

  2. Space out our lambda expression for readability: PEP 8 spacing and “Readability counts.”

  3. Move our lambda expression into a variable for improved clarity: “Beautiful is better than ugly.”

def get_all_odds(numbers):
    is_odd = lambda x: x % 2
    odd_list = list(filter(is_odd, numbers))
    return odd_list
  1. Just return our odd_list value instead of using a pointless variable: “Simple is better than complex.”

  2. Use a def instead of a lambda (everyone understands plain old functions): PEP 8 and “Explicit is better than implicit.” and “Simple is better than complex.”

def get_all_odds(numbers):
    def is_odd(num): return num % 2
    return list(filter(is_odd, numbers))
  1. Replace this filter with a list comprehension that does the same thing: “Complex is better than complicated.”

  2. Remove is_odd function because it’s fairly simple: “Complex is better than complicated.”

  3. Explicitly state that n % 2 != 0 is what we’re looking for: “Explicit is better than implicit.”

  4. Add brief but descriptive docstring: PEP 8 “Explicit is better than implicit.” and “Now is better than never.” Because when else are we really going to write documentation?

def get_all_odds(numbers):
    """Return all odd numbers in the given list."""
    return [n for n in numbers if n % 2 != 0]

Has Odds

The has_odds method we started with is:

def has_odds(numbers):
    odds = get_all_odds(numbers)
    at_least_one_odd = len(odds) > 0
    if at_least_one_odd:
        return True
    else:
        return False
  1. Replace if statement with a simple return statement: “Sparse is better than dense.” and “If the implementation is easy to explain, it may be a good idea.” and “Simple is better than complex.”

  2. Remove unnecessary at_least_one_odd variable that is immediately returned: “Simple is better than complex.”

def has_odds(numbers):
    odds = get_all_odds(numbers)
    return len(odds) > 0
  1. Remove unnecessary variable which is immediately used: “Simple is better than complex.” and “Beautiful is better than ugly.”

  2. Rely on truthiness of list (non-empty list is True): “Beautiful is better than ugly.” and “Simple is better than complex.”

def has_odds(numbers):
    return bool(get_all_odds(numbers))
  1. Improve performance by using a generator expression (any will return False if no values exist and return True when it finds the first item, so it is potentially more efficient): “Simple is better than complex.” and “Flat is better than nested.”

  2. Refactor code to use is_odd function (which can be used by both functions): “Beautiful is better than ugly.”

  3. Add missing docstrings: “Beautiful is better than ugly.” and “Now is better than never.”

def get_all_odds(numbers):
    """Return all odd numbers in the given list."""
    return [n for n in numbers if is_odd(n)]

def is_odd(n):
    """Return True if n is odd."""
    return n % 2 != 0

def has_odds(numbers):
    """Return True if given iterable contains any odd numbers."""
    return any(is_odd(n) for n in numbers)