星期六, 5月 09, 2015

python:將 list 內部分群

前面如何精簡地找出 list 中特定字的 index.
現實遇上的問題是 :  "一串 list, 自動分群, 同內容為一群"

前述討論串提供了好方法, 將 list 改成 dictionary
http://stackoverflow.com/questions/176918/finding-the-index-of-an-item-given-a-list-containing-it-in-python

a = ['foo','bar','baz','bar','any', 'foo', 'much']
l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
l['foo']
#[0, 5]
l ['much']
#[6]
l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}


上述等義先由 set 建立內容單一的集合, 再分群.
(老實說用 pyton, perl 會用太多內建物而失去效率. 建立 set 的過程顯然就分群了)

sub = set(a)
#set(['baz', 'foo', 'bar', 'any', 'much'])
def myset(val, a):
  return [i for i,v in enumerate(a) if v == val]
clusters = [myset(s, a) for s in sub]
# [[2], [0, 5], [1, 3], [4], [6]]

也可以再簡化為
b = [ [i for i,v in enumerate(a) if v is s] for s in sub ]
# [[2], [0, 5], [1, 3], [4], [6]]
跟 map 的結果是一樣的
map(lambda s: [i for i,v in enumerate(a) if v == s], set(a))
# [[2], [0, 5], [1, 3], [4], [6]]

希望有個 dictionary d,
d['baz'] = [2]
d['foo'] = [0,5]
d['bar'] = [1,3]
..

Dictionary 的生成方式, 要不是一個個  key:val, 要不用 zip (keys, val_list)
dict( zip(set(a), clusters) )

dict( zip(set(a), [[i for i,v in enumerate(a) if v == s] for s in set(a)] ) )
之後取用很方便
d['bar']
#[1, 3]










沒有留言: