Python中filter()和map()的区别

16

作为一个新手,我正在尝试弄清楚filter()和map()之间的区别。我编写了一个示例脚本如下:

def f(x): return x % 2 == 0
def m(y): return y * 2

list = [1,2,3,4]

flist = filter(f, list)
print(list)
print(flist)

mlist = map(m, list)
print(list)
print(mlist)

我们看到对于filter和map,我们传递一个列表,并将它们的输出分配给一个新列表。

这个脚本的输出是:

[1, 2, 3, 4]
[2, 4]
[1, 2, 3, 4]
[2, 4, 6, 8]

问题是,filter和map的函数调用看起来相同,如果我们交换传递给它们的函数的内容,它们会如何表现。

def f(x): return x * 2
def m(y): return y % 2 == 0

list = [1,2,3,4]

flist = filter(f, list)
print(list)
print(flist)

mlist = map(m, list)
print(list)
print(mlist)

这导致了。
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[False, True, False, True]

该过滤器评估函数,如果返回真,则返回传递的元素。 这里是函数。
def f(x): return x * 2

等于

def f(x): return x * 2 != 0

相比之下,map评估函数表达式并将结果作为项返回。因此,filter始终期望其函数执行比较类型的任务以过滤元素,而map则期望其函数评估语句以获得某些结果。

这个理解正确吗?


1
通过阅读附加的文档字符串,可以加深理解。在Python控制台中键入filter?map?,以简洁的形式阅读它们应该执行的操作。 - Uvar
12个回答

26

它们的工作方式有点不同,但你已经有了正确的想法。

Map将列表中的所有对象传递并允许你对其应用一个函数 Filter将列表中的所有对象传递并通过一个函数运行,创建一个新的列表,其中包含在该函数中返回True的所有对象。

这是一个例子

def square(num):
    return num * num

nums = [1, 2, 3, 4, 5]
mapped = map(square, nums)

print(*nums)
print(*mapped)

这个的输出是

1 2 3 4 5
1 4 9 16 25

这是一个 filter 的示例

def is_even(num):
    return num % 2 == 0


nums = [2, 4, 6, 7, 8]
filtered = filter(is_even, nums)

print(*nums)
print(*filtered)
这将会产生的输出结果是。
2 4 6 7 8
2 4 6 8

我已经在filter中传递了平方函数以查看结果,我得到了列表(nums)的所有值。这意味着filter函数基本上用于“条件检查”,当我在map()中传递is_even函数时,我会得到列表中每个数字的布尔值(例如,第一个项目是1,它是奇数,所以我得到false,以此类推)。因此,我认为map()基本上用于对列表项进行操作。我是正确的吗? - Synonian_raj

7

在map中:函数将应用于可迭代的所有对象。

在filter中:函数仅适用于满足表达式条件为True的可迭代对象。


6

据我理解,下面是map和filter之间的区别:

def even(num):
    if(num % 2 == 0):
        return 'Even'

num_list = [1,2,3,4,5]

打印(list(filter(even,num_list))) ->>>>>>>输出: [2, 4]

打印(list(map(even,num_list))) ->>>>>>>输出: [None, 'Even', None, 'Even', None]

所以,我们可以这样说: filter(): 格式化一个新的列表,其中包含满足特定条件的元素。 map(): 函数迭代遍历给定可迭代对象中的所有项目,并执行我们传递为参数的函数。


3

我认为你已经基本理解了。 Mapfilter 都是将函数应用于可迭代对象的方法。 在Map中,您可以使用多个可迭代对象。

definition : map(function_object, iterable1, iterable2,...)

而在 filter 中,只能使用一个可迭代对象

definition : filter(function_object, iterable)

在进一步筛选时,函数对象必须仅返回布尔值。为了举例,以下是具有多个可迭代输入的 Map。

list_a = [1, 2, 3]
list_b = [10, 20, 30]

map(lambda x, y: x + y, list_a, list_b) # Output: [11, 22, 33]

1

filter()和map()函数有一些不同。虽然map()函数接受普通函数,但filter()函数接受布尔函数。事实上,filter是带有条件逻辑、布尔逻辑的映射。


0

你的例子太准确了。 在过滤函数中,你需要传递一个函数和一个列表(该函数必须评估为真或假)。如果传入函数的元素返回true,则过滤函数将把传入的元素放入新列表中。而映射函数将取一个元素,通过一个函数传递它,并返回函数的输出并将其存储到新列表中。


0

这两者完全不同,只需看下面这个清晰的例子:

def sqr(x):
    return x%2==0

mp = map(sqr, [-1,0,1,2,3,4,5,6])
print(list(mp))

[假, 真, 假, 真, 假, 真, 假, 真]

fl = filter(sqr, [-1,0,1,2,3,4,5,6])
print(list(fl))

[0, 2, 4, 6]

正如您在这个清晰的例子中所看到的,filter 不关心 function 的结果!它只是检查列表项中哪些属于计算 def 的真值,并返回一个列表 [0, 2, 4, 6],这意味着我们得到了一组数字的真值结果。


0

map和filter的主要区别在于返回值。map将始终具有列表中元素的表示形式。而filter将过滤掉仅符合函数条件的元素。

def checkElementIn(a):

    nameList = ['b','a','l','l']

    if a in nameList:
        return a 

testList = ['r','e','d','b','a','l','l']

m_list = map(checkElementIn,testList)

for i in m_list:
    print(i)




b
a
l
l

f_list = filter(checkElementIn,testList)

for i in f_list:
    print(i)

b
a
l
l


0
#READ TIME 1 min. 
ages = [12,24,5,3,212,23,4,45,324,23]
age_filter = filter(lambda age : age >= 18, ages)
print(list(age_filter)) # filter gives result if there is condition

age_map = list(map(lambda age : age >= 18, ages))
print(age_map) # map will give boolean status but not actual values if 
condition

age_map_vals = list(map(lambda age : age * 18, ages))
print(age_map_vals) # here in map, condition is not given (means : 
multiplication will be performed with all elements)

# MAP AND FILTER WITH LIST OF WORDS
goats = ['EMINEM', '2upac', 'Dr.dre', 'snoop dog']
animals_filter = list(filter(lambda x : x != '2upac', goats))
print(animals_filter) # here condition > x != '2upac' is given

uppercase_map = list(map(lambda x : x.upper(), goats))
print(uppercase_map) # here condition is not given in map (means : 
x.upper() will applied to all elements)

0

一个可以通过手动实现 filtermap 来说明两者之间的差异:

def map(func, iterable): # simplified version taking only one iterable for better comparison
    """
    Produces function results for all elements in iterable
    """
    for element im iterable:
        yield func(element) 

def filter(func, iterable):
    """
    Produces those elements in iterable for which function result is truthy
    """
    for element im iterable:
        if func(element):
            yield element

请注意,您可以使用map来实现filter功能。
from itertools import tee  # allow duplicating lazy iterator

def filter(func, iterable):
    # independent clones of iterable, beyond scope of question
    i1, i2 = tee(iterable)  

    return (e for e, r in zip(i1, map(func, i2)) if r)

这个实现当然没有什么意义,但是展示了一些东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接