The map()
Python 中的 function 是一个内置函数,用于将函数应用于可迭代对象(数组、列表、元组、字典、集合)中的每个项目并返回一个迭代器。
这使得它对于转换可迭代数据非常有用。
Python map() 函数的语法
Python 的语法map()
功能很简单。它需要一个函数和一个或多个可迭代对象,并将该函数应用于可迭代中的每一项:
map(function, iterable, ...)
使用的主要好处之一map()
功能是可读性和效率。它允许您对可迭代中的每个项目执行操作,而无需使用显式 for 循环,这在处理大量数据时速度更快,正如您将在本教程后面看到的那样。
考虑以下示例:
def add_two(x):
return x + 2
numbers = [1, 2, 3, 4, 5]
addition = map(add_two, numbers)
print(list(addition))
Output:
[3, 4, 5, 6, 7]
这里我们定义一个函数add_two()
它接受一个整数作为输入并返回该整数加 2。然后我们使用这个函数map()
,这适用于add_two()
到数字列表中的每个项目。
结果是一个新列表,其中每个元素都是原始列表中对应的元素增加 2。
map()的返回类型
当你使用Python时map()
函数,它不会立即返回结果列表。相反,它返回一个iterator.
这是一个在迭代结果时即时生成结果的对象,这比一次生成所有结果更节省内存。
下面是一个简单的例子来演示这一点:
def multiply_by_two(x):
return x * 2
numbers = [1, 2, 3, 4, 5]
result = map(multiply_by_two, numbers)
print(result)
print(list(result))
Output:
<map object at 0x7f216e6f5970>
[2, 4, 6, 8, 10]
第一个打印语句打印地图对象本身,它是一个迭代器。第二个打印语句将映射对象转换为列表,强制生成所有结果。
您可以在 for 循环中使用返回的迭代器,将其转换为列表或元组,或者由接受可迭代对象作为输入的函数使用。
Python 2 与 Python 3 中的 map() 函数
虽然整体概念和用法map()
函数保持不变,Python 2 和 Python 3 之间的实现有一个关键的区别。
在Python 2中,map()
返回一个列表:
# Python 2
numbers = [1, 2, 3, 4, 5]
result = map(lambda x: x**2, numbers)
print(result) # Output: [1, 4, 9, 16, 25]
在Python 3中,map()
返回一个迭代器:
# Python 3
numbers = [1, 2, 3, 4, 5]
result = map(lambda x: x**2, numbers)
print(result) # Output: <map object at 0x10d238d30>
print(list(result)) # Output: [1, 4, 9, 16, 25]
这一变化使得map()
Python 3 中的内存效率更高,因为整个结果列表不是一次性生成的,而是在迭代结果时一次生成一个。
传递多个可迭代对象
在上面的例子中,我们使用了map()
具有单个可迭代的函数。事实上,map()
函数还可以将多个可迭代对象作为参数。
当与多个可迭代对象一起使用时,映射函数将以并行方式将其函数应用于可迭代对象的项。
这意味着它将函数应用于每个可迭代的第一项,然后应用于每个可迭代的第二项,依此类推。
函数必须采用的参数数量应与可迭代的数量相对应。
def add_numbers(x, y):
return x + y
numbers1 = [1, 2, 3, 4, 5]
numbers2 = [10, 20, 30, 40, 50]
result = map(add_numbers, numbers1, numbers2)
print(list(result))
Output:
[11, 22, 33, 44, 55]
在这个例子中,我们定义了一个函数add_numbers()
它接受两个参数并返回它们的总和。然后我们使用map()
具有此函数和两个数字列表的函数。
The map()
功能适用add_numbers()
列表中的每对项目(每个列表中的第一个项目,每个列表中的第二个项目等)并返回一个迭代器。我们将此迭代器转换为列表并打印结果的总和列表。
使用 Lambda 函数
Lambda 函数(lambda 表达式),也称为匿名函数,是使用 lambda 表达式定义的小型未命名函数。lambda
关键词。
与我们上面使用的自定义函数不同,您可以在map()
功能来创建快速转换。
以下是如何使用 lambda 函数map()
:
numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, numbers)
print(list(squared))
Output:
[1, 4, 9, 16, 25]
这里,lambda 函数接受一个输入x
并返回x
平方。我们使用这个函数map()
和一个数字列表,以及map()
将 lambda 函数应用于列表中的每个数字。结果是一个新的数字平方列表。
带有字典的 map() 函数
您可以使用map()
也可以与词典一起使用。需要注意的是,当使用字典时map()
,该函数默认应用于字典的键。
操作按键
def make_upper(key):
return key.upper()
fruit_colors = {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}
result = map(make_upper, fruit_colors)
print(list(result))
Output:
['APPLE', 'BANANA', 'GRAPE']
在此示例中,make_upper()
函数用于将字典键转换为大写。我们使用内置的map()
函数,适用于make_upper()
到字典中的每个键。
操纵价值观
如果你想操作字典的值,你可以使用dict.values()
method:
def add_exclamation(value):
return value + '!'
fruit_colors = {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}
result = map(add_exclamation, fruit_colors.values())
print(list(result))
Output:
['red!', 'yellow!', 'purple!']
在这里,add_exclamation()
函数为字典中的每个值添加感叹号。我们将这些值传递给map()
,这适用于add_exclamation()
给每一位。
速度比较
The map()
功能通常比手册更快for
循环,因为它是用 C 实现的并且可以利用向量化运算。
我使用 timeit 模块进行了简单的速度比较。使用简单的操作,将列表或数组中的每个数字加倍。
我用的是timeit
Python 中的模块来测量使用每种方法执行此操作所需的时间。
这是一个实验计划:
- 我创建了一个列表100万个号码.
- I measured the time it takes to double each number in the list using the following methods:
- Python
map
功能
- 列表理解
- For loop
我将每个操作运行 10 次并取平均值以获得更准确的测量。
import timeit
size = 10**6
lst = list(range(size))
# Define the operation (doubling each number)
operation = lambda x: x * 2
# Define the number of runs for the benchmark
runs = 10
# Benchmark the map function
start = timeit.default_timer()
for _ in range(runs):
result = list(map(operation, lst))
map_time = (timeit.default_timer() - start) / runs
# Benchmark list comprehension
start = timeit.default_timer()
for _ in range(runs):
result = [operation(x) for x in lst]
list_comp_time = (timeit.default_timer() - start) / runs
# Benchmark for loop
start = timeit.default_timer()
for _ in range(runs):
result = []
for x in lst:
result.append(operation(x))
for_loop_time = (timeit.default_timer() - start) / runs
print(map_time)
print(list_comp_time)
print(for_loop_time)
Output:
0.1796810700005153
0.18024229000147898
0.3354743200005032
如您所见,map
函数比列表理解稍快,并且两者都比标准快得多for
loop.
map() 和 filter() 之间的区别
虽然map()
and filter()
函数的相似之处在于它们都接受一个函数和一个可迭代对象作为参数,但它们有不同的用途。
The map()
function 将给定函数应用于可迭代的每个项目并返回结果列表。另一方面,filter()
function 从可迭代对象的元素构造一个列表,函数返回 true。
下面是一个例子来说明差异:
numbers = [1, 2, 3, 4, 5]
# Using map function to square the numbers
result_map = map(lambda x: x**2, numbers)
print(list(result_map)) # Output: [1, 4, 9, 16, 25]
# Using filter function to get only even numbers
result_filter = filter(lambda x: x % 2 == 0, numbers)
print(list(result_filter)) # Output: [2, 4]
在上面的例子中,map()
将 lambda 函数应用于每个元素,因此结果的长度与输入列表相同。filter()
但是,应用 lambda 函数并仅保留函数返回 True 的那些元素。
使用 map() 解决的现实问题
为了进一步说明该功能的强大功能和多功能性map()
函数,让我们看看如何使用它来解决现实世界的问题。
数据转换
假设您正在处理客户评论数据集,并且需要通过将文本全部小写并删除标点符号来规范化文本。
您可以定义一个转换函数,然后使用map()
将此函数应用于数据集中的每个评论:
import string
# Define the transformation function
def normalize_text(text):
text = text.lower() # Convert to lowercase
text = text.translate(str.maketrans('', '', string.punctuation)) # Remove punctuation
return text
reviews = ["Great product!", "I love it.", "Best purchase I've made."]
normalized_reviews = map(normalize_text, reviews)
print(list(normalized_reviews))
Output:
['great product', 'i love it', 'best purchase ive made']