TL DR::如何最好地使用map
到filter
基于逻辑索引的列表?
提供列表:
values = ['1', '2', '3', '5', 'N/A', '5']
我想map
使用以下功能并将结果用于filter
我的列表。我可以使用filter
和其他方法来做到这一点,但主要是想了解是否可以仅使用map
来做到这一点。
功能:
def is_int(val):
try:
x = int(val)
return True
except ValueError:
return False
尝试的解决方案:
[x for x in list(map(is_int, values)) if x is False]
以上内容为我提供了我需要的值。但是,它不返回索引或不允许逻辑索引。我曾尝试做其他可笑的事情,例如:
[values[x] for x in list(map(is_int, values)) if x is False]
以及其他许多显然不起作用的东西。
我认为自己可以做的事
values[[x for x in list(map(is_int, values)) if x is False]]
预期结果:
['N/A']
答案 0 :(得分:4)
[v for v in values if not is_int(v)]
如果有并行的布尔值列表:
[v for v, b in zip(values, [is_int(x) for x in values]) if not b]
答案 1 :(得分:3)
您可以使用下面编写的不包含任何地图功能的简单代码段来获得预期的结果
preventDefault()
而且,如果您想严格使用[x for x in values if is_int(x) is False]
功能,那么下面的代码段将为您提供帮助
map
答案 2 :(得分:1)
map
并不是正确的工作工具,因为它会转换值,而您只想检查它们即可。如果有的话,您正在寻找filter
,但必须先“逆向”过滤功能:
>>> values = ['1', '2', "foo", '3', '5', 'N/A', '5']
>>> not_an_int = lambda x: not is_int(x)
>>> list(filter(not_an_int, values))
['foo', 'N/A']
但是,在实践中,我宁愿使用带条件的列表理解。
答案 3 :(得分:1)
您可以使用itertools
的一些帮助,并通过否定原始函数的输出来执行此操作,因为我们希望它在不为int的情况下返回True
。
from itertools import compress
from operator import not_
list(compress(values, map(not_, map(is_int, values))))
['N/A']
答案 4 :(得分:1)
您不能单独使用map()
进行归约。根据其定义,map()保留项数(例如,参见here)。
另一方面,reduce操作意味着可以执行所需的操作。在Python中,这些通常可以通过生成器表达式来实现,或者对于功能更强的倾斜式编程器,可以通过filter()来实现。可能存在其他非原始方法,但它们实质上可以归结为两种方法之一,例如:
values = ['1', '2', '3', '5', 'N/A', '5']
list(filter(lambda x: not is_int(x), values))
# ['N/A']
但是,如果要合并map()
的结果以用于切片中,则仅靠Python不能做到这一点。
但是,NumPy完全支持您想要的内容,只是结果不会是列表:
import numpy as np
np.array(values)[list(map(lambda x: not is_int(x), values))]
# array(['N/A'], dtype='<U3')
(或者您可以以实现此行为的方式定义自己的容器)。
话虽这么说,在Python中使用以下生成器表达式代替map()
/ filter()
是很普遍的。
filter(func, items)
大致等同于:
item for item in items if func(item)
同时
map(func, items)
大致等同于:
func(item) for item in items
及其组合:
filter(f_func, map(m_func, items))
大致等同于:
m_func(item) for item in items if f_func(item)
答案 5 :(得分:0)
并非完全是我的初衷,而是从这个问题中学到的东西,我们可以执行以下操作(计算效率可能较低)。这几乎类似于@aws_apprentice的答案。显然,最好使用filter
和/或列表理解:
from itertools import compress
list(compress(values, list(map(lambda x: not is_int(x), values))))
或仅由@aws_apprentice建议:
from itertools import compress
list(compress(values, map(lambda x: not is_int(x), values)))