python 相当于 filter() 获取两个输出列表(即列表的分区)

发布于 2024-10-10 00:19:51 字数 273 浏览 4 评论 0原文

假设我有一个列表和一个过滤功能。使用类似

>>> filter(lambda x: x > 10, [1,4,12,7,42])
[12, 42]

I 的东西可以获得符合条件的元素。是否有一个函数可以使用它输出两个列表,一个元素匹配,一个剩余元素?我可以调用 filter() 函数两次,但这有点难看:)

编辑:元素的顺序应该保留,并且我可能多次拥有相同的元素。

Let's say I have a list, and a filtering function. Using something like

>>> filter(lambda x: x > 10, [1,4,12,7,42])
[12, 42]

I can get the elements matching the criterion. Is there a function I could use that would output two lists, one of elements matching, one of the remaining elements? I could call the filter() function twice, but that's kinda ugly :)

Edit: the order of elements should be conserved, and I may have identical elements multiple times.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

仅此而已 2024-10-17 00:19:52

试试这个:

def partition(pred, iterable):
    trues = []
    falses = []
    for item in iterable:
        if pred(item):
            trues.append(item)
        else:
            falses.append(item)
    return trues, falses

用法:

>>> trues, falses = partition(lambda x: x > 10, [1,4,12,7,42])
>>> trues
[12, 42]
>>> falses
[1, 4, 7]

itertools Recipes

from itertools import filterfalse, tee

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 filterfalse(pred, t1), filter(pred, t2)

配方来自Python 3.x文档。在 Python 2.x 中,filterfalse 称为 ifilterfalse

Try this:

def partition(pred, iterable):
    trues = []
    falses = []
    for item in iterable:
        if pred(item):
            trues.append(item)
        else:
            falses.append(item)
    return trues, falses

Usage:

>>> trues, falses = partition(lambda x: x > 10, [1,4,12,7,42])
>>> trues
[12, 42]
>>> falses
[1, 4, 7]

There is also an implementation suggestion in itertools recipes:

from itertools import filterfalse, tee

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 filterfalse(pred, t1), filter(pred, t2)

The recipe comes from the Python 3.x documentation. In Python 2.x filterfalse is called ifilterfalse.

山有枢 2024-10-17 00:19:52
>>> def partition(l, p):
...     return reduce(lambda x, y: (x[0]+[y], x[1]) if p(y) else (x[0], x[1]+[y]), l,  ([], []))
... 
>>> partition([1, 2, 3, 4, 5], lambda x: x < 3)
([1, 2], [3, 4, 5])

上面的代码有一点丑陋但更快的版本:

def partition(l, p):
    return reduce(lambda x, y: x[0].append(y) or x if p(y) else x[1].append(y) or x, l,  ([], []))

这是第二次编辑,但我认为这很重要:

 def partition(l, p):
     return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], []))

第二次和第三次与上面的迭代一样快,但代码更少。

>>> def partition(l, p):
...     return reduce(lambda x, y: (x[0]+[y], x[1]) if p(y) else (x[0], x[1]+[y]), l,  ([], []))
... 
>>> partition([1, 2, 3, 4, 5], lambda x: x < 3)
([1, 2], [3, 4, 5])

and a little uglier but faster version of the above code:

def partition(l, p):
    return reduce(lambda x, y: x[0].append(y) or x if p(y) else x[1].append(y) or x, l,  ([], []))

This is second edit, but I think it matters:

 def partition(l, p):
     return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], []))

The second and the third are as quick as the iterative one upper but are less code.

神也荒唐 2024-10-17 00:19:52

TL;DR

已接受、得票最多的答案 [1],作者:马克·拜尔斯

def 分区(pred,可迭代):
    真值 = []
    假=[]
    对于可迭代中的项目:
        如果预测(项目):
            trues.append(项目)
        别的:
            falses.append(项目)
    返回真值、假值

是最简单且最
最快。

对不同方法进行基准测试

可以对所建议的不同方法进行分类
大致分为三个类别,

  1. 通过 lis.append 进行简单的列表操作,返回一个 2 元组
    列表,
  2. lis.append 通过函数方法介导,返回一个 2 元组
    列表,
  3. 使用 itertools 中给出的规范配方
    文档,返回一个 2 元组(宽松地说)生成器。

下面是这三种技术的普通实现,首先
函数式方法,然后是itertools,最后是两种不同的方法
直接列表操作的实现,替代方案是
使用 False 为零,True 是一种技巧。

请注意,这是 Python3 - 因此 reduce 来自 functools -
并且该OP请求一个像(positives, negatives)这样的元组,但是我的
实现全部返回(负数,正数)...

$ ipython
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import functools
   ...: 
   ...: def partition_fu(p, l, r=functools.reduce):
   ...:     return r(lambda x, y: x[p(y)].append(y) or x, l, ([], []))
   ...: 

In [2]: import itertools
   ...: 
   ...: def partition_it(pred, iterable,
   ...:               filterfalse=itertools.filterfalse,
   ...:               tee=itertools.tee):
   ...:     t1, t2 = tee(iterable)
   ...:     return filterfalse(pred, t1), filter(pred, t2)
   ...: 

In [3]: def partition_li(p, l):
   ...:     a, b = [], []
   ...:     for n in l:
   ...:         if p(n):
   ...:             b.append(n)
   ...:         else:
   ...:             a.append(n)
   ...:     return a, b
   ...: 

In [4]: def partition_li_alt(p, l):
   ...:     x = [], []
   ...:     for n in l: x[p(n)].append(n)
   ...:     return x
   ...: 

我们需要一个谓词来应用于我们的列表和列表(再次,松散地
说)进行操作。

In [5]: p = lambda n:n%2

In [6]: five, ten = range(50000), range(100000)

为了克服测试 itertools 方法中的问题,那就是
joeln 报道
2013 年 10 月 31 日 6:17

废话。您已经计算了构建该项目所需的时间
filterfalsefilter 中的生成器,但您尚未迭代
通过输入或调用 pred 一次!的优点
itertools 的秘诀是它不会具体化任何列表,或者看起来
输入比必要的更进一步。它调用 pred 两次
经常发生,而且花费的时间几乎是 Byers 等人的两倍。

我想到了一个空循环,它只是实例化所有的情侣
不同分区返回的两个可迭代对象中的元素数量
功能。

首先我们使用两个固定列表来了解
隐含的重载(使用非常方便的 IPython 魔法%timeit

In [7]: %timeit for e, o in zip(five, five): pass
4.21 ms ± 39.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

接下来我们使用不同的实现,一个接着一个

In [8]: %timeit for e, o in zip(*partition_fu(p, ten)): pass
53.9 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [9]: %timeit for e, o in zip(*partition_it(p, ten)): pass
44.5 ms ± 3.84 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [10]: %timeit for e, o in zip(*partition_li(p, ten)): pass
36.3 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [11]: %timeit for e, o in zip(*partition_li_alt(p, ten)): pass
37.3 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [12]:

。注释

最简单的方法也是最快的方法。

使用 x[p(n)] 技巧是,嗯,没用,因为在每一步你
必须对数据结构建立索引,这会给你带来轻微的惩罚 - 这是
然而,如果你想说服衰退中的幸存者,那么很高兴知道
python化的文化。

函数式方法,操作上等价于
替代的 append 实现速度慢约 50%,可能是由于
事实上,我们有一个额外的(w/r 到谓词评估)函数
调用每个列表元素。

itertools 方法具有以下(通常的)优点: ❶ 没有
潜在的大列表被实例化,并且 ❷ 输入列表没有被实例化
如果您打破消费者循环,则完全处理,但是当我们
使用它会比较慢,因为需要在两者上应用谓词
tee 的末端

除此之外,

我已经爱上了 object.mutate() 或 object 习语,
Marii 曝光
他们的答案显示
解决问题的功能性方法——恐怕迟早,
我要滥用它。

脚注

[1] 截至今天,即 2017 年 9 月 14 日,已被接受并获得最多投票 — 但当然,我对我的这个答案抱有最高的希望!

TL;DR

The accepted, most voted answer [1] by Mark Byers

def partition(pred, iterable):
    trues = []
    falses = []
    for item in iterable:
        if pred(item):
            trues.append(item)
        else:
            falses.append(item)
    return trues, falses

is the simplest and the
fastest.

Benchmarking the different approaches

The different approaches that had been suggested can be classified
broadly in three categories,

  1. straightforward list manipulation via lis.append, returning a 2-tuple
    of lists,
  2. lis.append mediated by a functional approach, returning a 2-tuple
    of lists,
  3. using the canonical recipe given in the itertools fine
    documentation, returning a 2-tuple of, loosely speaking, generators.

Here follows a vanilla implementation of the three techniques, first
the functional approach, then itertools and eventually two different
implementations of direct list manipulation, the alternative being
using the False is zero, True is one trick.

Note that this is Python3 — hence reduce comes from functools
and that OP request a tuple like (positives, negatives) but my
implementations all return (negatives, positives)

$ ipython
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:51:32) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import functools
   ...: 
   ...: def partition_fu(p, l, r=functools.reduce):
   ...:     return r(lambda x, y: x[p(y)].append(y) or x, l, ([], []))
   ...: 

In [2]: import itertools
   ...: 
   ...: def partition_it(pred, iterable,
   ...:               filterfalse=itertools.filterfalse,
   ...:               tee=itertools.tee):
   ...:     t1, t2 = tee(iterable)
   ...:     return filterfalse(pred, t1), filter(pred, t2)
   ...: 

In [3]: def partition_li(p, l):
   ...:     a, b = [], []
   ...:     for n in l:
   ...:         if p(n):
   ...:             b.append(n)
   ...:         else:
   ...:             a.append(n)
   ...:     return a, b
   ...: 

In [4]: def partition_li_alt(p, l):
   ...:     x = [], []
   ...:     for n in l: x[p(n)].append(n)
   ...:     return x
   ...: 

We need a predicate to apply to our lists and lists (again, loosely
speaking) on which to operate.

In [5]: p = lambda n:n%2

In [6]: five, ten = range(50000), range(100000)

To overcome the problem in testing the itertools approach, that was
reported by joeln on
Oct 31 '13 at 6:17

Nonsense. You've calculated the time taken to construct the
generators in filterfalse and filter, but you've not iterated
through the input or called pred once! The advantage of the
itertools recipe is that it does not materialise any list, or look
further ahead in the input than necessary. It calls pred twice as
often and takes almost twice as long as Byers et al.

I have thought of a void loop that just instantiates all the couples
of elements in the two iterables returned by the different partition
functions.

First we use two fixed lists to have an idea of the
overload implied (using the very convenient IPython's magic %timeit)

In [7]: %timeit for e, o in zip(five, five): pass
4.21 ms ± 39.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Next we use the different implementations, one after the other

In [8]: %timeit for e, o in zip(*partition_fu(p, ten)): pass
53.9 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [9]: %timeit for e, o in zip(*partition_it(p, ten)): pass
44.5 ms ± 3.84 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [10]: %timeit for e, o in zip(*partition_li(p, ten)): pass
36.3 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [11]: %timeit for e, o in zip(*partition_li_alt(p, ten)): pass
37.3 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [12]:

Comments

The plainest of the approaches is also the fastest one.

Using the x[p(n)] trick is, ehm, useless because at every step you
have to index a data structure, giving you a slight penalty — it's
however nice to know if you want to persuade a survivor of a declining
culture at pythonizing.

The functional approach, that is operatively equivalent to the
alternative append implementation, is ~50% slower, possibly due to
the fact that we have an extra (w/r to predicate evaluation) function
call for each list element.

The itertools approach has the (customary) advantages that ❶ no
potentially large list is instantiated and ❷ the input list is not
entirely processed if you break out of the consumer loop, but when we
use it it is slower because of the need to apply the predicate on both
ends of the tee

Aside

I've fallen in love with the object.mutate() or object idiom that
was exposed by Marii
in their answer showing
a functional approach to the problem — I'm afraid that, sooner or later,
I'm going to abuse it.

Footnotes

[1] Accepted and most voted as today, Sep 14 2017 — but of course I have the highest hopes for this answer of mine!

满意归宿 2024-10-17 00:19:52

我认为 groupby 在这里可能更相关:

http://docs.python.org/library/itertools.html #it​​ertools.groupby

例如,将列表拆分为奇数和偶数(或者可以是任意数量的组):

>>> l=range(6)
>>> key=lambda x: x % 2 == 0
>>> from itertools import groupby
>>> {k:list(g) for k,g in groupby(sorted(l,key=key),key=key)}
    {False: [1, 3, 5], True: [0, 2, 4]}

I think groupby might be more relevant here:

http://docs.python.org/library/itertools.html#itertools.groupby

For example, splitting a list into odd and even numbers (or could be an arbitrary number of groups):

>>> l=range(6)
>>> key=lambda x: x % 2 == 0
>>> from itertools import groupby
>>> {k:list(g) for k,g in groupby(sorted(l,key=key),key=key)}
    {False: [1, 3, 5], True: [0, 2, 4]}
怪我鬧 2024-10-17 00:19:52

您可以查看 django.utils。 function.partition 解决方案:

def partition(predicate, values):
    """
    Splits the values into two sets, based on the return value of the function
    (True/False). e.g.:

        >>> partition(lambda x: x > 3, range(5))
        [0, 1, 2, 3], [4]
    """
    results = ([], [])
    for item in values:
        results[predicate(item)].append(item)
    return results

在我看来,这是这里介绍的最优雅的解决方案。

这部分没有记录,只能在 https:// 上找到源代码/docs.djangoproject.com/en/dev/_modules/django/utils/function/

You can look at django.utils.functional.partition solution:

def partition(predicate, values):
    """
    Splits the values into two sets, based on the return value of the function
    (True/False). e.g.:

        >>> partition(lambda x: x > 3, range(5))
        [0, 1, 2, 3], [4]
    """
    results = ([], [])
    for item in values:
        results[predicate(item)].append(item)
    return results

In my opinion it's the most elegant solution presented here.

This part is not documented, only source code can be found on https://docs.djangoproject.com/en/dev/_modules/django/utils/functional/

故事与诗 2024-10-17 00:19:52

如果您的列表中没有重复的元素,您绝对可以使用 set:

>>> a = [1,4,12,7,42]
>>> b = filter(lambda x: x > 10, [1,4,12,7,42])
>>> no_b = set(a) - set(b)
set([1, 4, 7])

或者您可以通过可理解的列表来完成:

>>> no_b = [i for i in a if i not in b]

注意:它不是一个函数,但只需知道第一个 fitler() 结果,您就可以推断出没有的元素很大程度上是你的过滤标准。

If you don't have duplicate element in your list you can definitely use set:

>>> a = [1,4,12,7,42]
>>> b = filter(lambda x: x > 10, [1,4,12,7,42])
>>> no_b = set(a) - set(b)
set([1, 4, 7])

or you can do by a list comprehensible:

>>> no_b = [i for i in a if i not in b]

N.B: it's not a function but just knowing the first fitler() result you can deduce the element that didn't much your filter criterion .

睫毛上残留的泪 2024-10-17 00:19:52

我正好有这个要求。我不喜欢 itertools 配方,因为它涉及两次单独的数据传递。这是我的实现:

def filter_twoway(test, data):
    "Like filter(), but returns the passes AND the fails as two separate lists"
    collected = {True: [], False: []}
    for datum in data:
        collected[test(datum)].append(datum)
    return (collected[True], collected[False])

I just had exactly this requirement. I'm not keen on the itertools recipe since it involves two separate passes through the data. Here's my implementation:

def filter_twoway(test, data):
    "Like filter(), but returns the passes AND the fails as two separate lists"
    collected = {True: [], False: []}
    for datum in data:
        collected[test(datum)].append(datum)
    return (collected[True], collected[False])
拒绝两难 2024-10-17 00:19:52
from itertools import ifilterfalse

def filter2(predicate, iterable):
    return filter(predicate, iterable), list(ifilterfalse(predicate, iterable))
from itertools import ifilterfalse

def filter2(predicate, iterable):
    return filter(predicate, iterable), list(ifilterfalse(predicate, iterable))
韬韬不绝 2024-10-17 00:19:52

现有的答案要么将可迭代对象划分为两个列表,要么低效地将其划分为两个生成器。这是一个将可迭代对象有效地划分为两个生成器的实现,即对于可迭代对象中的每个元素最多调用一次谓词函数。您可能想要使用此版本的一个实例是,如果您需要使用计算成本昂贵的谓词对非常大(甚至无限)的可迭代对象进行分区。

from collections import deque

def partition(pred, iterable):
    seq = iter(iterable)
    true_buffer = deque()
    false_buffer = deque()
    def true_iter():
        while True:
            while true_buffer:
                yield true_buffer.popleft()
            item = next(seq)
            if pred(item):
                yield item
            else:
                false_buffer.append(item)
    def false_iter():
        while True:
            while false_buffer:
                yield false_buffer.popleft()
            item = next(seq)
            if not pred(item):
                yield item
            else:
                true_buffer.append(item)
    return true_iter(), false_iter()

基本上,这会遍历迭代器中的每个项目,检查谓词,如果正在使用相应的生成器,则生成它,或者将其放入另一个可迭代的缓冲区中。此外,每个生成器在检查原始可迭代对象之前都会首先从其缓冲区中提取项目。请注意,每个分区都有自己的缓冲区,每次迭代另一个分区时该缓冲区都会增长,因此此实现可能不适合一个分区比另一个分区迭代次数多得多的用例。

示例用例:

from itertools import count
from random import random

odds, evens = partition(lambda n: n % 2, count())
for _ in range(500):
    if random() < 0.5:
        print(next(odds))
    else:
        print(next(evens))

The existing answers either partition an iterable into two lists, or inefficiently partition it into two generators. Here is an implementation that efficiently partitions an iterable into two generators, i.e. the predicate function is called at most once for each element in the iterable. One instance where you might want to use this version is if your need to partition a very large (or even infinite) iterable with an expensive to compute predicate.

from collections import deque

def partition(pred, iterable):
    seq = iter(iterable)
    true_buffer = deque()
    false_buffer = deque()
    def true_iter():
        while True:
            while true_buffer:
                yield true_buffer.popleft()
            item = next(seq)
            if pred(item):
                yield item
            else:
                false_buffer.append(item)
    def false_iter():
        while True:
            while false_buffer:
                yield false_buffer.popleft()
            item = next(seq)
            if not pred(item):
                yield item
            else:
                true_buffer.append(item)
    return true_iter(), false_iter()

Basically, this steps through each item in the the iterator, checks the predicate, and either yields it, if the corresponding generator is being used, or puts it in the buffer for the other iterable. Additionally, each generator will first pull items from its buffer before checking the original iterable. Note that each partition has it's own buffer which grows each time the other partition is iterated, so this implementation may not be suitable for use cases where one partition is iterated much more than the other.

example use case:

from itertools import count
from random import random

odds, evens = partition(lambda n: n % 2, count())
for _ in range(500):
    if random() < 0.5:
        print(next(odds))
    else:
        print(next(evens))
羅雙樹 2024-10-17 00:19:52

每个人似乎都认为他们的解决方案是最好的,所以我决定使用 timeit 来测试所有这些解决方案。我使用“def is_odd(x): return x & 1”作为我的谓词函数,使用“xrange(1000)”作为可迭代函数。这是我的 Python 版本:

Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:52:43) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin

这是我的测试结果:

Mark Byers
1000 loops, best of 3: 325 usec per loop

cldy
1000 loops, best of 3: 1.96 msec per loop

Dan S
1000 loops, best of 3: 412 usec per loop

TTimo
1000 loops, best of 3: 503 usec per loop

这些都是相互比较的。现在,让我们尝试使用 Python 文档中给出的示例。

import itertools

def partition(pred, iterable,
              # Optimized by replacing global lookups with local variables
              # defined as default values.
              filter=itertools.ifilter,
              filterfalse=itertools.ifilterfalse,
              tee=itertools.tee):
    '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 filterfalse(pred, t1), filter(pred, t2)

这似乎有点快了。

100000 loops, best of 3: 2.58 usec per loop

itertools 示例代码以至少 100 倍的优势击败了所有竞争对手!其寓意是,不要不断地重新发明轮子。

Everyone seems to think that their solution is the best, so I decided to use timeit to test all of them. I used "def is_odd(x): return x & 1" as my predicate function, and "xrange(1000)" as the iterable. Here is my version of Python:

Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:52:43) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin

And here are the results of my testing:

Mark Byers
1000 loops, best of 3: 325 usec per loop

cldy
1000 loops, best of 3: 1.96 msec per loop

Dan S
1000 loops, best of 3: 412 usec per loop

TTimo
1000 loops, best of 3: 503 usec per loop

Those are all comparable to each other. Now, let's try using the example given in the Python documentation.

import itertools

def partition(pred, iterable,
              # Optimized by replacing global lookups with local variables
              # defined as default values.
              filter=itertools.ifilter,
              filterfalse=itertools.ifilterfalse,
              tee=itertools.tee):
    '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 filterfalse(pred, t1), filter(pred, t2)

This seems to be a bit faster.

100000 loops, best of 3: 2.58 usec per loop

The itertools example code beats all comers by a factor of at least 100! The moral is, don't keep re-inventing the wheel.

墨洒年华 2024-10-17 00:19:52

已经有很多好的答案了。我喜欢用这个:

def partition( pred, iterable ):
    def _dispatch( ret, v ):
        if ( pred( v ) ):
            ret[0].append( v )
        else:
            ret[1].append( v )
        return ret
    return reduce( _dispatch, iterable, ( [], [] ) )

if ( __name__ == '__main__' ):
    import random
    seq = range( 20 )
    random.shuffle( seq )
    print( seq )
    print( partition( lambda v : v > 10, seq ) )

Plenty of good answers already. I like to use this:

def partition( pred, iterable ):
    def _dispatch( ret, v ):
        if ( pred( v ) ):
            ret[0].append( v )
        else:
            ret[1].append( v )
        return ret
    return reduce( _dispatch, iterable, ( [], [] ) )

if ( __name__ == '__main__' ):
    import random
    seq = range( 20 )
    random.shuffle( seq )
    print( seq )
    print( partition( lambda v : v > 10, seq ) )
我们的影子 2024-10-17 00:19:52

用于附加到目标列表的简洁代码

    def partition(cond,inputList):
        a,b= [],[]
        for item in inputList:
            target = a if cond(item) else b
            target.append(item)
        return a, b


    >>> a, b= partition(lambda x: x > 10,[1,4,12,7,42])
    >>> a
    [12, 42]
    >>> b
    [1, 4, 7]

Concise code for appending to target list

    def partition(cond,inputList):
        a,b= [],[]
        for item in inputList:
            target = a if cond(item) else b
            target.append(item)
        return a, b


    >>> a, b= partition(lambda x: x > 10,[1,4,12,7,42])
    >>> a
    [12, 42]
    >>> b
    [1, 4, 7]
在巴黎塔顶看东京樱花 2024-10-17 00:19:52

一个等效问题的投票最高的三个答案建议使用itertools.tee()(如这里已经介绍的)以及两种更简单的方法。

The three top voted answers to an equivalent question propose to use itertools.tee() (as already covered here) and two even simpler approaches as wells.

小兔几 2024-10-17 00:19:52

collections.defaultdict 方法是排序操作的优秀助手。

import collections

input_list = ['a','b','ana','beta','gamma']
filter_key = lambda x: len(x) == 1    

## sorting code
cc = collections.defaultdict(list)
for item in input_list: cc[ filter_key(item) ].append( item )

print(cc)

此方法也适用于由 filter_key 函数生成的任意数量的类别。

The collections.defaultdict method is an excellent helper for sorting operations.

import collections

input_list = ['a','b','ana','beta','gamma']
filter_key = lambda x: len(x) == 1    

## sorting code
cc = collections.defaultdict(list)
for item in input_list: cc[ filter_key(item) ].append( item )

print(cc)

This approach will also work for any number of categories generated by the filter_key function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文