内容简介:We’re excited to continue ourLast but not least, do check ourIn theory, articles like these shouldn’t be necessary — if you encounter a function you don’t understand well, the go-to source of knowledge is supposed to be the Python built-in
Mapping the knowledge onto you
We’re excited to continue our “Python Explained” series with another article — this time we’re taking a look at the map()
function. Its goal may appear rather simple (help the developer work with large sets of data), but there’s always more to learn. Here are some of the Python-focused content we produced as of late:
- Responsible Web Scraping: Gathering Data Ethically and Legally
- Python enumerate() Explained and Visualized
- “Learn Python the Hard Way”: a Detailed Book Review
- Python range() Explained and Visualized
- A Roundup Review of the Best Deep Learning Books
- Flask vs. Django: Let’s Choose the Right Framework for the Job
Last but not least, do check our Python interview questions out! In this article, we’ll examine the inner workings of the map()
function in Python. As always, we’re using Python 3.
Before We Begin…
In theory, articles like these shouldn’t be necessary — if you encounter a function you don’t understand well, the go-to source of knowledge is supposed to be the Python built-in help()
module.
C:\Python\Test_folder> Python Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>
You pass the function you want to learn about as the argument…
>>> help(map)
… and get an explanation that (hopefully) clears up all misunderstandings. Here’s what the Python help() module has to say about map()
:
Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted.
Well, the folks at the Python Foundation have condensed a lot of information into this neat little description — so much so that many novice Python programmers have a hard time understanding how they can apply map()
in their programs. It probably looks like this to a beginner Python programmer:
Quite easy to follow, don’t you think?
However, the explanation above introduces two terms which are essential to Python: iterator and iterable . Since they appear frequently throughout various Python documentation files, let’s explain them now:
- Iteration is a general computer science term; it refers to performing an action to a set of elements, one element at a time. A good example is the loop — it works with each individual item until the whole set of items is exhausted.
- An Iterable is an object that we can loop over (e.g. a string, a list, or a file). From the Iterable , we get the iterator .
- An iterator is an object that represents a stream of data; it returns the data one element at a time. It also remembers its position during iteration. Essentially, it governs how the iterable object should be iterated over .
With these terms defined, we can now move to the next point — analyzing what map()
does and how it can be applied.
So What Does map() Actually Do in Python?
The map()
function applies the function you provide to each item in an iterable. The result is a map object which is an iterator . Here’s the syntax of map()
:
map(func, *iterables)
Without map()
, we’d be forced to write complex code to “loop” the given function over a number of items. Let’s imagine a neat little experiment: we have a list of 10 words.
test_list = ["effort", "circle", "yearly", "woolen", "accept", "lurker", "island", "faucet", "glossy", "evader"]
We suspect that some of them may be abcderian (i.e. the letters appear in alphabetical order). We write a function called is_abecedarian
to check if the given word is abcderian:
def is_abecedarian(input_word): index = 0 for letter in input_word[0:-1]: if ord(input_word[index]) > ord(input_word[index + 1]): return False else: index += 1 return True
Now, we want to apply our function to the word list and create a new list which will hold True
and False
values, signifying whether some of the words are indeed abcderian. One method would involve initializing a new list, then using a for
loop to iterate over the list elements:
value_list = [] for item in test_list: value = is_abecedarian(item) value_list.append(value)
This will output:
[True, False, False, False, True, False, False, False, True, False]
Thanks to map()
, however, we can reduce the code above to a neat little one-liner:
map(is_abecedarian, test_list)
However, we should be mindful that map() doesn’t return a list — it returns a map object instead.
You might be curious which words are actually abcderian — let’s code the answer to your question:
for item in test_list: if is_abecedarian(item): print(f"The word '{item}' is abecedarian. :)") else: print(f"The word '{item}' is not abecedarian. (")
This will output:
The word 'effort' is abecedarian. :) The word 'circle' is not abecedarian. The word 'yearly' is not abecedarian. The word 'woolen' is not abecedarian. The word 'accept' is abecedarian. :) The word 'lurker' is not abecedarian. The word 'island' is not abecedarian. The word 'faucet' is not abecedarian. The word 'glossy' is abecedarian. :) The word 'evader' is not abecedarian.
We can also visualize this explanation to help you understand it even better:
Almost feels like magic
It’s also useful to define map and mapping — we can use the definitions provided by Allen B. Downey in his Think Python book:
-
map: A processing pattern that traverses a sequence and performs an operation on each element.
-
mapping: A relationship in which each element of one set corresponds to an element of another set.
Converting map() into a List, Tuple, and a Set
Since map()
doesn’t return a list/tuple/set, we need to take an extra step to convert the resulting map object :
def capitalize_word(input_word): return input_word.capitalize() map_object = map(capitalize_word, ['strength', 'agility', 'intelligence']) test_list = list(map_object) print(test_list) map_object = map(capitalize_word, ['health', 'mana', 'gold']) test_set = set(map_object) print(test_set) map_object = map(capitalize_word, ['armor', 'weapon', 'spell']) test_tuple = tuple(map_object) print(test_tuple)
This will output:
['Strength', 'Agility', 'Intelligence'] {'Mana', 'Health', 'Gold'} ('Armor', 'Weapon', 'Spell')
Combining map() with Lambda Expressions
From multiple lines to a pretty one-liner
Lambda expressions are a fine addition to our arsenal: combining them with map()
makes your Python program even smaller, code line-wise. Lambda expressions create anonymous functions , i.e. functions that aren’t bound to a specific identifier. Conversely, creating a function via the def
keyword bounds the function to its unique identifier (e.g. def my_function
creates an identifier my_function
).
However, lambda expressions have a set of limitations: each of them can only do one thing and only be used on one place . They’re often used in conjunction with other functions, so let’s see how can we utilize them and map()
simultaneously. For instance, we can turn the code below…
cities = ["caracas", "bern", "oslo", "ottawa", "bangkok"] def capitalize_word(input_word): return input_word.capitalize() capitalized_cities = map(capitalize_word, cities)
… into a more concise version:
cities = ["caracas", "bern", "oslo", "ottawa", "bangkok"] capitalized_cities = map(lambda s: s.capitalize(), cities)
However, there’s a caveat: both map()
and lambda expressions provide the ability to condense multiple-line code into a single line. While this functionality is pretty awesome, we need to keep in mind one of the golden rules of programming: Code is read more often than it is written.
This means that both map()
and lambda expressions can improve code brevity , but sacrifice code clarity . Sadly, there aren’t really any clear guidelines on how readable your code should be — you’ll figure this yourself out as your programming experience grows.
Using map() to Iterate over a Dictionary
Naturally, map()
is well-suited for scenarios when you want to iterate over a dictionary. Let’s imagine we have a dictionary containing the prices of apples, pears, and cherries. We need to update the price list by applying a 15% discount to it. Here’s how we can do it:
price_list = { "pear": 0.60, "cherries": 0.90, "apple": 0.35, } def calulates_discount(item_price): return (item_price[0], round(item_price[1] * 0.85, 2)) new_price_list = dict(map(calulates_discount, price_list.items()))
The output will be:
{'pear': 0.51, 'cherries': 0.77, 'apple': 0.3}
Combining map() with Lambda Expressions to Iterate over a Dictionary
Programming is especially interesting when you start to combine multiple functions — a good example is using map()
and lambda expressions simultaneously to iterate over a dictionary. In the code snippet below, we initialize a list of dictionaries and pass each dictionary as a parameter to the lambda function.
list_of_ds = [{'user': 'Jane', 'posts': 18}, {'user': 'Amina', 'posts': 64}] map(lambda x: x['user'], list_of_ds) # Output: ['Jane', 'Amina'] map(lambda x: x['posts'] * 10, list_of_ds) # Output: [180, 640] map(lambda x: x['user'] == "Jane", list_of_ds) # Output: [True, False]
map() Alternatives: List Comprehension
Like with all technologies/products/techniques/approaches/etc., some Python developers consider the map()
() function to be somewhat un-Pythonic (i.e. not following the spirit and design philosophies of how Python programs should be built). They suggest using list comprehensions instead so that
map(f, iterable)
turns into
[f(x) for x in iterable]
Speed- and performance-wise, map()
and list comprehensions are roughly equal, so it’s highly unlikely that you’ll see a significant decrease in execution times — experienced Python developer Wesley Chun addressed this question in his talk Python 103: Memory Model & Best Practices (the discussion starts around 5:50 if the timestamp didn’t work correctly).
Conclusion
Phew — turns out this map()
function in Python isn’t so complicated after all! To solidify your knowledge, however, you should play around with these examples and tweak them — by breaking and fixing these code snippets, you may very well run into certain aspects of the map()
function that we didn’t cover. Good luck!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。