0

基本的に私がやりたいことは、オブジェクトの 2 つのリストを取得し、いくつかのテストに基づいて、結果が か かによって 2 つのリストに分割することTrueですFalsefilter()それが入っているか出ているかを判断する代わりに、どのリスト/イテレータに行くかを判断することを除いて、何をするかの並べ替え。私は次を使用してこの試みを行いましたitertools.groupby()

import random
from itertools import groupby

class FooObject(object):
    def __init__(self):
        self.key = random.choice((True, False))

    def __repr__(self):
        return '<Foo: %s>' % self.key

foos = [FooObject() for _ in range(10)]
left, right = [], []

groups = groupby(sorted(foos, key=lambda o: o.key), lambda o: o.key)
for k, group in groups:
    if k:
        right = list(group)
    else:
        left = list(group)

print left
print right

これで仕事は完了ですが、もっと明確で簡単な方法があるかどうか疑問に思っています。(または同等のリスト内包表記) を使用して 2 つのパスで実行できることに気付きfilter()ましたが、それは楽しいことでしょうか?

4

2 に答える 2

1

バケットが 2 つしかない場合は、三項を使用できます。

d={'left':[],'right':[]}
for e in (random.random() for i in xrange(50)):
    d['left' if e<0.5 else 'right'].append(e)

3 つ以上のバケットがある場合は、既に定義されているキーを返す関数を使用するか、リストでデフォルトの dict を使用します。

def f(i):
   return int(i*10)

DoL=defaultdict(list)
for e in (random.random() for i in xrange(50)):
   DoL[f(e)].append(e)
于 2013-02-11T23:11:07.910 に答える
1

次の関数は、ソースを 1 回だけ消費し、辞書のようなオブジェクトを返します。その各メンバーはジェネレーターであり、ソースから可能な限り遅延して値を生成します。

def partition(it, fun):

    class x(object):
        def __init__(self):
            self.buf = {}

        def flush(self, val):
            for p in self.buf.get(val, []):
                yield p
            self.buf.pop(val, None)

        def __getitem__(self, val):
            for p in self.flush(val): yield p
            while True:
                try:
                    p = next(it)
                except StopIteration:
                    break
                v = fun(p)
                if v == val:
                    yield p
                else:
                    self.buf.setdefault(v, []).append(p)
            for p in self.flush(val): yield p

    return x()

使用例:

def primes(): # note that this is an endless generator
    yield 2
    p, n = [], 3
    while True:
        if all(n % x for x in p):
            p.append(n)
            yield n
        n += 2


p = partition(primes(), lambda x: x % 3)
# each member of p is endless as well

for x in p[1]:
    print x
    if x > 200: break

for x in p[2]:
    print x
    if x > 200: break
于 2013-02-11T22:16:24.773 に答える