可能重复:
python equivalent of filter() getting two output lists (i.e. partition of a list)
我在python中有一个数组,想要将它分成两个数组,一个是元素与谓词匹配,另一个是元素不匹配。
是否有比以下更简单的方式(或更多Pythonic):
>>> 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])
答案 0 :(得分:2)
您目前拥有的内容比其他任何方式都更简单,更有效。
以下是一些关于如何重写此代码的潜在选项,以及为什么我认为您的版本更好:
答案 1 :(得分:1)
def partition(a,pred):
f1 = set(filter(pred,a))
f2 = set(a) - f1
return f1,f2
更pythonic ......但不确定它是否更快
[编辑]我不认为订单被保留......(并且在两条评论中都有更好的答案和链接)
答案 2 :(得分:1)
另一种说同样的话。请注意,两个列表的顺序相反。
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
答案 3 :(得分:0)
您可以访问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对大型阵列特别有效。对于小的,不是那么多。
答案 4 :(得分:0)
#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)
答案 5 :(得分:-1)
不是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])