16

私はよく、Pythonで順序付けされていないコレクションをバケット化したいです。itertools.groubpy正しい種類のことを行いますが、ほとんどの場合、最初にアイテムを並べ替えて、消費される前にイテレータをキャッチするためにマッサージが必要です。

標準のPythonモジュールまたは単純なPythonイディオムのいずれかを使用して、この動作をすばやく取得する方法はありますか?

>>> bucket('thequickbrownfoxjumpsoverthelazydog', lambda x: x in 'aeiou')
{False: ['t', 'h', 'q', 'c', 'k', 'b', 'r', 'w', 'n', 'f', 'x', 'j', 'm', 'p',
    's', 'v', 'r', 't', 'h', 'l', 'z', 'y', 'd', 'g'],
 True: ['e', 'u', 'i', 'o', 'o', 'u', 'o', 'e', 'e', 'a', 'o']}
>>> bucket(xrange(21), lambda x: x % 10)
{0: [0, 10, 20],
 1: [1, 11],
 2: [2, 12],
 3: [3, 13],
 4: [4, 14],
 5: [5, 15],
 6: [6, 16],
 7: [7, 17],
 8: [8, 18],
 9: [9, 19]}
4

5 に答える 5

22

これは以前に何度か出てきました- (1)(2)(3) -そしてレシピにはパーティションレシピがありitertoolsますが、私の知る限り、標準ライブラリには何もありません..数週間驚いたが前にaccumulate、それで、最近そこに何が潜んでいるのか誰が知っていますか?:^)

この動作が必要な場合は、

from collections import defaultdict

def partition(seq, key):
    d = defaultdict(list)
    for x in seq:
        d[key(x)].append(x)
    return d

そして私の一日を続けてください。

于 2012-10-04T04:44:07.503 に答える
5

これが簡単な2つのライナーです

d = {}
for x in "thequickbrownfoxjumpsoverthelazydog": d.setdefault(x in 'aeiou', []).append(x)

編集:

完全を期すために、他のケースを追加するだけです。

d={}
for x in xrange(21): d.setdefault(x%10, []).append(x)
于 2012-10-04T04:33:46.030 に答える
2

partition()これは、述語がブール値である場合の上記の変形であり、 dict/ defaultdict:のコストを回避します。

def boolpartition(seq, pred):
    passing, failing = [], []
    for item in seq:
        (passing if pred(item) else failing).append(item)
    return passing, failing

使用例:

>>> even, odd = boolpartition([1, 2, 3, 4, 5], lambda x: x % 2 == 0)
>>> even
[2, 4]
>>> odd
[1, 3, 5]
于 2015-01-26T12:16:35.453 に答える
2

pandas.DataFrame以下も機能する場合は、pd.cut()

from sklearn import datasets
import pandas as pd

# import some data to play with
iris = datasets.load_iris()
df_data = pd.DataFrame(iris.data[:,0])  # we'll just take the first feature

# bucketize
n_bins = 5
feature_name = iris.feature_names[0].replace(" ", "_")
my_labels = [str(feature_name) + "_" + str(num) for num in range(0,n_bins)]
pd.cut(df_data[0], bins=n_bins, labels=my_labels)

降伏

0      0_1
1      0_0
2      0_0
[...]

を設定しない場合labels、出力は次のようになります

0       (5.02, 5.74]
1      (4.296, 5.02]
2      (4.296, 5.02]
[...]
于 2017-10-30T02:53:39.197 に答える
-1

編集:

DSMの回答を出発点として使用して、もう少し簡潔で一般的な回答を次に示します。

d = defaultdict(list)
map(lambda x: d[x in 'aeiou'].append(x),'thequickbrownfoxjumpsoverthelazydog')

また

d = defaultdict(list)
map(lambda x: d[x %10].append(x),xrange(21))

これが2つのライナーです。

d = {False:[],True:[]}
filter(lambda x: d[True].append(x) if x in 'aeiou' else d[False].append(x),"thequickbrownfoxjumpedoverthelazydogs")

もちろん、これはワンライナーにすることができます:

d = {False:[],True:[]};filter(lambda x: d[True].append(x) if x in 'aeiou' else d[False].append(x),"thequickbrownfoxjumpedoverthelazydogs")
于 2012-10-04T04:44:45.707 に答える