繁体   English   中英

使用Python的地图进行逻辑索引

[英]Logical Indexing with Python's map

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']
[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]

您可以使用下面编写的不包含任何地图功能的简单代码段来获得预期的结果

[x for x in values if is_int(x) is False]

而且,如果您想严格使用map功能,则以下代码段将为您提供帮助

[values[i] for i,y in enumerate(list(map(is_int,values))) if y is False]

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']

但是在实践中,我宁愿使用带条件的列表理解。

您可以使用itertools的一些帮助,并通过否定原始函数的输出来执行此操作,因为我们希望它在不是int的情况下返回True

from itertools import compress
from operator import not_

list(compress(values, map(not_, map(is_int, values))))

['N/A']

您不能单独使用map()进行归约。 根据其定义,map()保留项的数量(请参见例如此处 )。 另一方面,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)

不完全是我的初衷,而是从这个问题中学到的东西,我们可以做到以下几点(计算效率可能较低)。 这几乎类似于@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)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM