2012-09-28 79 views
3

我發現自己經常在Python中使用扁平列表創建索引列表。這是一個常見的任務,我想知道是否有一個標準的實用程序,我應該使用它。將數組索引

上下文是這樣的:給定一個數組,我需要使用一些關鍵字來創建一個小數組的字典來進行分組。

e.g:
["Andy","Alice","Bob","Beth","Charlie"]成爲
{"A":["Andy","Alice"],"B":["Bob","Beth"],"C":["Charlie"]}

我的解決辦法是這樣的:

def make_index(data,key,value=lambda x:x): 
    d={} 
    for item in data: 
     k = key(item) 
     v = value(item) 
     try: d[k].append(v) 
     except KeyError: d[k]=[v] 
    return d 

很簡單,所有的,但我會重新發明的東西,實現更好一些呢?

回答

5

你可以做同樣的稍微簡單了defaultdict

from collections import defaultdict 

def make_index(data,key,value=lambda x:x): 
    d=defaultdict(list) 
    for item in data: 
     d[key(item)].append(value(item)) 
    return d 

使用defaultdict比使用.setdefault(),這將是另一個選項更快。

+0

明顯快於GROUPBY也...這是有點suprising ... –

+1

@JoranBeasley:這是你做整理殺死它。 –

3

不知道爲什麼itertools的答案被刪除,但我在寫一個自己:

from itertools import groupby 
def make_index(data, key = lambda x: x[0]): 
    return {key: list(gr) for key, gr in 
     groupby(sorted(data, key=key), key=key)} 

In [3]: make_index(["Andy","Alice","Bob","Beth","Charlie"]) 
Out[3]: {'A': ['Andy', 'Alice'], 'B': ['Bob', 'Beth'], 'C': ['Charlie']} 

In [4]: make_index(["Andy","Alice","Bob","Beth","Charlie"], key=lambda x: len(x)) 
Out[4]: {3: ['Bob'], 4: ['Andy', 'Beth'], 5: ['Alice'], 7: ['Charlie']} 
+0

這當然是一個更有意思的答案,但它似乎需要的時間是Martijn版本的兩倍,可能是因爲它是多步驟變換。 – tylerl

+0

@tylerl是的,Martjijn的版本不需要對列表進行排序。 –