2013-03-22 15 views
5

私はPythonがこれを行うための組み込みを持っているように感じます。アイテムのリストを取得し、それらを共通のキーを持つアイテムのリストにマッピングする辞書に変換します。キーで項目をグループ化していますか?

それは行うのに十分に簡単です:

# using defaultdict 
lookup = collections.defaultdict(list) 
for item in items: 
    lookup[key(item)].append(item) 

# or, using plain dict 
lookup = {} 
for item in items: 
    lookup.setdefault(key(item), []).append(item) 

しかし、これは組み込み関数がいいだろうというユースケースを十分に頻繁です。私のような、それを自分自身を実現することができます。これは、いくつかの重要な点でitertools.groupbyと異なる

def grouped(iterable, key): 
    result = {} 
    for item in iterable: 
     result.setdefault(key(item), []).append(item) 
    return result 

lookup = grouped(items, key) 

groupbyから同じ結果を得るために、あなたは少し醜いである、これを実行する必要があると思います:

lookup = dict((k, list(v)) for k, v in groupby(sorted(items, key=key), key)) 

いくつかの例:

>>> items = range(10) 
>>> grouped(items, lambda x: x % 2) 
{0: [0, 2, 4, 6, 8], 1: [1, 3, 5, 7, 9]} 

>>> items = 'hello stack overflow how are you'.split() 
>>> grouped(items, len) 
{8: ['overflow'], 3: ['how', 'are', 'you'], 5: ['hello', 'stack']} 

良い方法はありますか?

+1

「これは十分な使用例が多い」ということはわかりません。私はそれをほとんど使用せず、必要なときに 'defaultdict'を使うだけで完璧です。 AFAIKには、あなたが望むものだけを内蔵しているものはありません。 – Bakuriu

+0

あなたはおそらく正しいでしょうが、私の一部はこれがgroupbyとしての組み込みのものと同様に考えています。 – FogleBird

答えて

3

また、この質問をcomp.lang.pythonに掲載しました。これは実際には組み込み関数を保証するのに十分な共通点ではないようです。したがって、明白なアプローチを使用するのが最適です。彼らは働き、彼らは読める。

# using defaultdict 
lookup = collections.defaultdict(list) 
for item in items: 
    lookup[key(item)].append(item) 

# or, using plain dict 
lookup = {} 
for item in items: 
    lookup.setdefault(key(item), []).append(item) 

は、私は私の質問を削除するつもりだったが、私はここにもこれを残す可能性がある場合には、誰もが情報を探して、それを越えつまずきます。

+1

上記と同じように機能するが、 'groupby'とおおよそ同じAPIを使用する方法については、私の答えを見てください。 – tobych

1

あなたはgroupbyとほぼ同じAPIで何かを望んでいた場合は、使用できます。

def groupby2(iterable, keyfunc): 
    lookup = collections.defaultdict(list) 
    for item in iterable: 
     lookup[keyfunc(item)].append(item) 
    return lookup.iteritems() 

だから、上記のあなたの例と同じですが、あなたの「ルックアップテーブルのiteritemsを返す関数の中に作られましたベアー。

関連する問題