我在我的团队的代码中看到了重复几次的模式,看起来像这样
numbers = [1, 2, 3, 4]
even_numbers = [n for n in numbers if n % 2 == 0]
odd_numbers = [n for n in numbers if n % 2 != 0]
我想知道某个地方是否有某个功能(我环顾四周,但是找不到)
numbers = [1, 2, 3, 4]
even_numbers, odd_numbers = fork(numbers, lambda x: x % 2 == 0)
因此,我正在寻找的该函数将收到一个可迭代的函数,并返回两个列表,一个列表将是与提供的条件匹配的值,另一个列表是不符合条件的值。
python的标准库周围是否有实现这一目标的东西?
答案 0 :(得分:11)
我通常将其称为sift
,但是partition
也可以。
另一种无需itertools的实现方式
def sift(iterable, predicate):
t = []
f = []
for value in iterable:
(t if predicate(value) else f).append(value)
return (t, f)
even, odd = sift([1, 2, 3, 4, 5], lambda x: x % 2 == 0)
编辑:对于稍微复杂一点的实现,速度大约要快30%(无论如何在我的Python安装上):
def sift2(iterable, predicate):
t = []
f = []
ta = t.append
fa = f.append
for value in iterable:
(ta if predicate(value) else fa)(value)
return (t, f)
答案 1 :(得分:3)
您可以使用以下功能:
from itertools import filterfalse, tee
def fork(pred, iterable):
'Use a predicate to partition entries into false entries and true entries'
t1, t2 = tee(iterable)
return list(filterfalse(pred, t1)), list(filter(pred, t2))
来源:itertools
答案 2 :(得分:2)
@jonrsharpe建议后的完整代码。
import itertools
def fork(iterable):
"Returns list of even, odd elements of a list"
t1, t2 = itertools.tee(iterable)
pred = lambda i: i % 2 == 0
return list(filter(pred, t2)), list(itertools.filterfalse(pred, t1))
odd, even = fork([1,2,3,4,5])
print(odd)
print(even)
替代的numpy版本,对于大型数组而言可能更快
import numpy as np
def fork(iterable):
"Returns array of even, odd elements of an array"
iterable_array = np.asarray(iterable)
mask = (iterable_array % 2 == 0)
return iterable_array[~mask], iterable_array[mask]
答案 3 :(得分:2)
我没有在标准库中找到满足您要求的任何内容。我建议您使用这个用户定义的实现,它根本没有优化,但是非常简单易读:
def myFunc(iterable, func):
first = [i for i in iterable if func(i)]
second = [i for i in iterable if not func(i)]
return first,second
numbers = [1, 2, 3, 4]
even_numbers, odd_numbers = myFunc(numbers, lambda x: x % 2 == 0)
print(even_numbers) # [2, 4]
print(odd_numbers) # [1, 3]
答案 4 :(得分:0)
您可以创建自己的函数:
l = [1, 2, 3, 4]
def fork(l,key):
return list(filter(key,l)), [i for i in l if i not in list(filter(key,l))]
even_numbers, odd_numbers = fork(l, lambda x: x % 2 == 0)
print(even_numbers)
print(odd_numbers)
输出:
[2, 4]
[1, 3]