python中基于谓词的数组分区

python中基于谓词的数组分区,python,arrays,Python,Arrays,可能重复: 我在python中有一个数组,希望将其拆分为两个数组,一个数组中的元素匹配谓词,另一个数组中的元素不匹配谓词 是否有比以下更简单的方法(或更通灵的方法): >>> def partition(a, pred): ... ain = [] ... aout = [] ... for x in a: ... if pred(x): ... ain.append(x) ... else: ... aout.append

可能重复:

我在python中有一个数组,希望将其拆分为两个数组,一个数组中的元素匹配谓词,另一个数组中的元素不匹配谓词

是否有比以下更简单的方法(或更通灵的方法):

>>> def partition(a, pred):
...   ain = []
...   aout = []
...   for x in a:
...     if pred(x):
...       ain.append(x)
...     else:
...       aout.append(x)
...   return (ain, aout)
...
>>> partition(range(1,10), lambda x: x%3 == 1)
([1, 4, 7], [2, 3, 5, 6, 8, 9])
更多的蟒蛇。。。但不确定它是否更快


[编辑]我不认为秩序得到了维护。。。(两条评论中都有更好的答案和链接)

您有权访问NumPy吗?Numpy的索引功能使得根据某些条件选择Numpy
ndarray
的条目非常容易。比如说

>>> import numpy as np
>>> a = np.arange(1, 10)
>>> condition = (a % 3 == 1)
>>> a[condition]
array([1, 4, 7])
>>> a[~condition]
array([2, 3, 5, 6, 8, 9])

NumPy对于大型阵列特别有效。对于小的,没有那么多。

你现在拥有的比任何其他方法都更简单、更有效

#from http://docs.python.org/dev/library/itertools.html#itertools-recipes

def partition(pred, iterable):
    'Use a predicate to partition entries into false entries and true entries'
    # partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
    t1, t2 = tee(iterable)
    return ifilterfalse(pred, t1), filter(pred, t2)
以下是一些关于如何重写此代码的潜在选项,以及我认为您的版本更好的原因:

  • 使用集合-顺序不保留,仅适用于可散列内容
  • 使用tee/filter/ifilterfalse-取决于结果的使用方式,最终会使用更多内存,并迭代两次
  • 使用numpy-不适用于一般的iterables,需要迭代两次才能得到两种情况下的结果

不是那么的
Pythonic
,而是有点功能性:

>>> partition = lambda xs, p: reduce(lambda (a, b), c: p(c) and (a + [c], b) or (a, b + [c]), xs, ([], []))
>>> print partition(range(1, 10), lambda x: x % 3 == 1)
([1, 4, 7], [2, 3, 5, 6, 8, 9])

只是说同样的话的另一种方式。请注意,这两个列表的顺序是相反的

def partition(a, pred):
    aout_ain = [], []
    for x in a:
        aout_ain[pred(x)].append(x)
    return aout_ain
如果您需要先输入“ins”,只需添加一个
not

def partition(a, pred):
    ain_aout = [], []
    for x in a:
        ain_aout[not pred(x)].append(x)
    return ain_aout

在应该赊账的地方赊账。嗯,我试着在发布前搜索&找不到它——谢谢!
def partition(a, pred):
    ain_aout = [], []
    for x in a:
        ain_aout[not pred(x)].append(x)
    return ain_aout