One place for hosting & domains

      Function

      How To Use the Python Map Function


      Introduction

      We can use the Python built-in function map() to apply a function to each item in an iterable (like a list or dictionary) and return a new iterator for retrieving the results. map() returns a map object (an iterator), which we can use in other parts of our program. We can also pass the map object to the list() function, or another sequence type, to create an iterable.

      The syntax for the map() function is as follows:

      map(function, iterable, [iterable 2, iterable 3, ...])
      

      Instead of using a for loop, the map() function provides a way of applying a function to every item in an iterable. Therefore it can often be more performant since it is only applying the function one item at a time rather than making copies of the items into another iterable. This is particularly useful when working on programs processing large data sets. map() can also take multiple iterables as arguments to the function by sending one item from each iterable to the function at a time.

      In this tutorial, we’ll review three different ways of working with map(): with a lambda function, with a user-defined function, and finally with a built-in function using multiple iterable arguments.

      Using a Lambda Function

      The first argument to map() is a function, which we use to apply to each item. Python calls the function once for every item in the iterable we pass into map() and it returns the manipulated item within a map object. For the first function argument, we can either pass a user-defined function or we can make use of lambda functions, particularly when the expression is less complex.

      The syntax of map() with a lambda function is as follows:

      map(lambda item: item[] expression, iterable)
      

      With a list like the following, we can implement a lambda function with an expression that we want to apply to each item in our list:

      numbers = [10, 15, 21, 33, 42, 55]
      

      To apply an expression against each of our numbers, we can use map() and lambda:

      mapped_numbers = list(map(lambda x: x * 2 + 3, numbers))
      

      Here we declare an item in our list as x. Then we add our expression. We pass in our list of numbers as the iterable for map().

      In order to receive the results of this immediately we print a list of the map object:

      print(mapped_numbers)
      

      Output

      [23, 33, 45, 69, 87, 113]

      We have used list() so that the map object is returned to us as a list, rather than a less human-readable object like: <map object at 0x7fc250003a58>. The map object is an iterator over our results, so we could loop over it with for or we can use list() to turn it into a list. We’re doing this here because it’s a good way to review the results.

      Ultimately map() is most useful when working with large datasets, so we would likely work with the map object further, and generally would not be using a constructor like list() on them.

      For smaller datasets, list comprehensions may be more suitable, but for the purposes of this tutorial we’re using a small dataset to demonstrate map().

      Implementing a User-defined Function

      Similarly to a lambda we can use a function we have defined to apply to an iterable. While lambda functions are more useful to implement when you’re working with a one-line expression, user-defined functions are more appropriate when the expression grows in complexity. Furthermore, when we need to pass another piece of data to the function that you’re applying to your iterable, user-defined functions can be a better choice for readability.

      For example, in the following iterable, each item is a dictionary that contains different details about each of our aquarium creatures:

      aquarium_creatures = [
          {"name": "sammy", "species": "shark", "tank number": 11, "type": "fish"},
          {"name": "ashley", "species": "crab", "tank number": 25, "type": "shellfish"},
          {"name": "jo", "species": "guppy", "tank number": 18, "type": "fish"},
          {"name": "jackie", "species": "lobster", "tank number": 21, "type": "shellfish"},
          {"name": "charlie", "species": "clownfish", "tank number": 12, "type": "fish"},
          {"name": "olly", "species": "green turtle", "tank number": 34, "type": "turtle"}
      ]
      

      We’ve decided that all the aquarium creatures are in fact going to move into the same tank. We need to update our records to reflect that all of our creatures are moving into tank 42. To have map() access each dictionary and each key:value pair in the dictionaries, we construct a nested function:

      def assign_to_tank(aquarium_creatures, new_tank_number):
          def apply(x):
              x["tank number"] = new_tank_number
              return x
          return map(apply, aquarium_creatures)
      

      We define an assign_to_tank() function that takes aquarium_creatures and new_tank_number as parameters. In assign_to_tank() we pass apply() as the function to map() on the final line. The assign_to_tank function will return the iterator resulting from map().

      apply() takes x as an argument, which represents an item in our list — a single dictionary.

      Next we define that x is the "tank number" key from aquarium_creatures and that it should store the passed in new_tank_number. We return each item after applying the new tank number.

      We call assign_to_tank() with our list of dictionaries and the new tank number we want to replace for each creature:

      assigned_tanks = assign_to_tank(aquarium_creatures, 42)
      

      Once the function completes we have our map object stored in the assigned_tanks variable, which we turn into a list and print:

      print(list(assigned_tanks))
      

      We’ll receive the following output from this program:

      Output

      [{'name': 'sammy', 'species': 'shark', 'tank number': 42, 'type': 'fish'}, {'name': 'ashley', 'species': 'crab', 'tank number': 42, 'type': 'shellfish'}, {'name': 'jo', 'species': 'guppy', 'tank number': 42, 'type': 'fish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': 42, 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': 42, 'type': 'fish'}, {'name': 'olly', 'species': 'green turtle', 'tank number': 42, 'type': 'turtle'}]

      We’ve mapped the new tank number to our list of dictionaries. Using a function that we define, we can incorporate map() to apply the function efficiently on each item of the list.

      Using a Built-in Function with Multiple Iterables

      In the same way as lambda functions or our own defined functions, we can use Python built-in functions with map(). To apply a function with multiple iterables, we pass in another iterable name following the first one. For example, using the pow() function that takes in two numbers to find the power of the base number to the provided exponent.

      Here we have our lists of integers that we would like to use with pow():

      base_numbers = [2, 4, 6, 8, 10]
      powers = [1, 2, 3, 4, 5]
      

      Next we pass in pow() as our function into map() and provide the two lists as our iterables:

      numbers_powers = list(map(pow, base_numbers, powers))
      
      print(numbers_powers)
      

      map() will apply the pow() function to the same item in each list to provide the power. Therefore our results will show 2**1, 4**2, 6**3, and so on:

      Output

      [2, 16, 216, 4096, 100000]

      If we were to provide map() with an iterable that was longer than the other, map() would stop calculating once it reaches the end of the shortest iterable. In the following program we’re extending base_numbers with three additional numbers:

      base_numbers = [2, 4, 6, 8, 10, 12, 14, 16]
      powers = [1, 2, 3, 4, 5]
      
      numbers_powers = list(map(pow, base_numbers, powers))
      
      print(numbers_powers)
      

      As a result, nothing will change within the calculation of this program and so it will still yield the same result:

      Output

      [2, 16, 216, 4096, 100000]

      We’ve used the map() function with a Python built-in function and have seen that it can handle multiple iterables. We’ve also reviewed that map() will continue to process multiple iterables until it has reached the end of the iterable with the fewest items.

      Conclusion

      In this tutorial, we’ve learned the different ways of using the map() function in Python. Now you can use map() with your own function, a lambda function, and with any other built-in functions. You can also implement map() with functions that require multiple iterables.

      In this tutorial, we printed the results from map() immediately to a list format for demonstration purposes. In our programs we would typically use the returned map object to further manipulate the data.

      If you would like to learn more Python, check out our How To Code in Python 3 series and our Python topic page. To learn more about working with data sets in functional programming, check out our article on the filter() function.



      Source link

      How To Use the Python Filter Function


      Introduction

      The Python built-in filter() function can be used to create a new iterator from an existing iterable (like a list or dictionary) that will efficiently filter out elements using a function that we provide. An iterable is a Python object that can be “iterated over”, that is, it will return items in a sequence such that we can use it in a for loop.

      The basic syntax for the filter() function is:

      filter(function, iterable)
      

      This will return a filter object, which is an iterable. We can use a function like list() to make a list of all the items returned in a filter object.

      The filter() function provides a way of filtering values that can often be more efficient than a list comprehension, especially when we’re starting to work with larger data sets. For example, a list comprehension will make a new list, which will increase the run time for that processing. This means that after our list comprehension has completed its expression, we’ll have two lists in memory. However, filter() will make a simple object that holds a reference to the original list, the provided function, and an index of where to go in the original list, which will take up less memory.

      In this tutorial, we’ll review four different ways of using filter(): with two different iterable structures, with a lambda function, and with no defined function.

      Using filter() with a Function

      The first argument to filter() is a function, which we use to decide whether to include or filter out each item. The function is called once for every item in the iterable passed as the second argument and each time it returns False, the value is dropped. As this argument is a function, we can either pass a normal function or we can make use of lambda functions, particularly when the expression is less complex.

      Following is the syntax of a lambda with filter():

      filter(lambda item: item[] expression, iterable)
      

      With a list, like the following, we can incorporate a lambda function with an expression against which we want to evaluate each item from the list:

      creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']
      

      To filter this list to find the names of our aquarium creatures that start with a vowel, we can run the following lambda function:

      print(list(filter(lambda x: x[0].lower() in 'aeiou', creature_names)))
      

      Here we declare an item in our list as x. Then we set our expression to access the first character of each string (or character “zero”), so x[0]. Lowering the case of each of the names ensures this will match letters to the string in our expression, 'aeiou'.

      Finally we pass the iterable creature_names. Like in the previous section we apply list() to the result in order to create a list from the iterator filter() returns.

      The output will be the following:

      Output

      ['Ashley', 'Olly']

      This same result can be achieved using a function we define:

      creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']
      
      def names_vowels(x):
        return x[0].lower() in 'aeiou'
      
      filtered_names = filter(names_vowels, creature_names)
      
      print(list(filtered_names))
      

      Our function names_vowels defines the expression that we will implement to filter creature_names.

      Again, the output would be as follows:

      Output

      ['Ashley', 'Olly']

      Overall, lambda functions achieve the same result with filter() as when we use a regular function. The necessity to define a regular function grows as the complexity of expressions for filtering our data increases, which is likely to promote better readability in our code.

      Using None with filter()

      We can pass None as the first argument to filter() to have the returned iterator filter out any value that Python considers “falsy”. Generally, Python considers anything with a length of 0 (such as an empty list or empty string) or numerically equivalent to 0 as false, thus the use of the term “falsy.”

      In the following case we want to filter our list to only show the tank numbers at our aquarium:

      aquarium_tanks = [11, False, 18, 21, "", 12, 34, 0, [], {}]
      

      In this code we have a list containing integers, empty sequences, and a boolean value.

      filtered_tanks = filter(None, aquarium_tanks)
      

      We use the filter() function with None and pass in the aquarium_tanks list as our iterable. Since we have passed None as the first argument, we will check if the items in our list are considered false.

      print(list(filtered_tanks))
      

      Then we wrap filtered_tanks in a list() function so that it returns a list for filtered_tanks when we print.

      Here we see the output shows only the integers. All the items that evaluated to False, that are equivalent to 0 in length, were removed by filter():

      Output

      [11, 25, 18, 21, 12, 34]

      Note: If we don’t use list() and print filtered_tanks we would receive a filter object something like this: <filter object at 0x7fafd5903240>. The filter object is an iterable, so we could loop over it with for or we can use list() to turn it into a list, which we’re doing here because it’s a good way to review the results.

      With None we have used filter() to quickly remove items from our list that were considered false.

      Using filter() with a List of Dictionaries

      When we have a more complex data structure, we can still use filter() to evaluate each of the items. For example, if we have a list of dictionaries, not only do we want to iterate over each item in the list — one of the dictionaries — but we may also want to iterate over each key:value pair in a dictionary in order to evaluate all the data.

      As an example, let’s say we have a list of each creature in our aquarium along with different details about each of them:

      aquarium_creatures = [
        {"name": "sammy", "species": "shark", "tank number": "11", "type": "fish"},
        {"name": "ashley", "species": "crab", "tank number": "25", "type": "shellfish"},
        {"name": "jo", "species": "guppy", "tank number": "18", "type": "fish"},
        {"name": "jackie", "species": "lobster", "tank number": "21", "type": "shellfish"},
        {"name": "charlie", "species": "clownfish", "tank number": "12", "type": "fish"},
        {"name": "olly", "species": "green turtle", "tank number": "34", "type": "turtle"}
      ]
      

      We want to filter this data by a search string we give to the function. To have filter() access each dictionary and each item in the dictionaries, we construct a nested function, like the following:

      def filter_set(aquarium_creatures, search_string):
          def iterator_func(x):
              for v in x.values():
                  if search_string in v:
                      return True
              return False
          return filter(iterator_func, aquarium_creatures)
      

      We define a filter_set() function that takes aquarium_creatures and search_string as parameters. In filter_set() we pass our iterator_func() as the function to filter(). The filter_set() function will return the iterator resulting from filter().

      The iterator_func() takes x as an argument, which represents an item in our list (that is, a single dictionary).

      Next the for loop accesses the values in each key:value pair in our dictionaries and then uses a conditional statement to check whether the search_string is in v, representing a value.

      Like in our previous examples, if the expression evaluates to True the function adds the item to the filter object. This will return once the filter_set() function has completed. We position return False outside of our loop so that it checks every item in each dictionary, instead of returning after checking the first dictionary alone.

      We call filter_set() with our list of dictionaries and the search string we want to find matches for:

      filtered_records = filter_set(aquarium_creatures, "2")    
      

      Once the function completes we have our filter object stored in the filtered_records variable, which we turn into a list and print:

      print(list(filtered_records))      
      

      We’ll see the following output from this program:

      Output

      [{'name': 'ashley', 'species': 'crab', 'tank number': '25', 'type': 'shellfish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': '21', 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': '12', 'type': 'fish'}]

      We’ve filtered the list of dictionaries with the search string 2. We can see that the three dictionaries that included a tank number with 2 have been returned. Using our own nested function allowed us to access every item and efficiently check each against the search string.

      Conclusion

      In this tutorial, we’ve learned the different ways of using the filter() function in Python. Now you can use filter() with your own function, a lambda function, or with None to filter for items in varying complexities of data structures.

      Although in this tutorial we printed the results from filter() immediately in list format, it is likely in our programs we would use the returned filter() object and further manipulate the data.

      If you would like to learn more Python, check out our How To Code in Python 3 series and our Python topic page.



      Source link