リストを辞書にマッピングする方法はありますか?私がやりたいことは、キーの名前を返す関数をそれに与え、値は元の値になります。例えば;
_somefunction(lambda a: a[0], ["hello", "world"])
=> {"h":"hello", "w":"world"}
_
(これは私がやりたい具体的な例ではありません。これを行うことができるmap()
のような汎用関数が必要です)
正確にそれを行う標準関数は存在しないと思いますが、組み込みのdictと内包を使用して簡単に作成できます。
def somefunction(keyFunction, values):
return dict((keyFunction(v), v) for v in values)
print somefunction(lambda a: a[0], ["hello", "world"])
出力:
{'h': 'hello', 'w': 'world'}
ただし、この関数に適切な名前を付けることは、実装するよりも困難です。読者のための演習として残しておきます。
Python 3では、この辞書内包表記構文を使用できます。
def foo(somelist):
return {x[0]:x for x in somelist}
あなたの質問を正しく理解できれば、map
、Zip
、およびdict
コンストラクターの組み合わせでこれを達成できると思います。
def dictMap(f, xs) :
return dict(Zip(map(f, xs), xs)
そしてより公正な実装:
def dictMap(f, xs) :
return dict((f(i), i) for i in xs)
一般的な関数でこれを行う場合は、ほぼ正しい質問をしていることになります。ただし、この例では、キー関数が重複を生成した場合の動作を指定していません。最後のものを残しますか?最初の1つ?同じ文字で始まるすべての単語のリストを作成しますか?これらの質問への回答は、設計者ではなく関数のユーザーが行うのが最適です。
これらをパラメーター化すると、より複雑ですが非常に一般的な機能になります。これは私が数年使ってきたものです:
def reduce_list(key, update_value, default_value, l):
"""Reduce a list to a dict.
key :: list_item -> dict_key
update_value :: key * existing_value -> updated_value
default_value :: initial value passed to update_value
l :: The list
default_value comes before l. This is different from functools.reduce,
because functools.reduce's order is wrong.
"""
d = {}
for k in l:
j = key(k)
d[j] = update_value(k, d.get(j, default_value))
return d
次に、次のようにして関数を記述できます。
reduce_list(lambda s:s, lambda s,old:s[0], '', ['hello', 'world'])
# OR
reduce_list(lambda s:s, lambda s,old: old or s[0], '', ['hello', 'world'])
最初または最後のWordを「h」などで開始するかどうかによって異なります。
ただし、この関数は非常に一般的であるため、ほとんどの場合、group_dict
やhistogram
などの他の関数の基礎となります。
def group_dict(l):
return reduce_list(lambda x:x, lambda x,old: [x] + old, [], l)
def histogram(l):
return reduce_list(lambda x:x, lambda x,total: total + 1, 0, l)
他の答えからヒントを得て、マップ操作を使用してこれを達成しました。これがあなたの質問に正確に答えるかどうかはわかりません。
mylist = ["hello", "world"]
def convert_to_dict( somelist ):
return dict( map( lambda x: (x[0], x), somelist ) )
final_ans = convert_to_dict( mylist )
print final_ans
>>> dict((a[0], a) for a in "hello world".split())
{'h': 'hello', 'w': 'world'}
添え字の代わりに関数を使用する場合は、operator.itemgetterを使用します。
>>> from operator import itemgetter
>>> first = itemgetter(0)
>>> dict((first(x), x) for x in "hello world".split())
{'h': 'hello', 'w': 'world'}
または関数として:
>>> dpair = lambda x : (first(x), x)
>>> dict(dpair(x) for x in "hello world".split())
{'h': 'hello', 'w': 'world'}
最後に、可能性として文字ごとに複数のWordが必要な場合は、collections.defaultdictを使用します。
>>> from collections import defaultdict
>>> words = defaultdict(set)
>>> addword = lambda x : words[first(x)].add(x)
>>> for Word in "hello house home hum world wry wraught".split():
addword(Word)
>>> print words['h']
set(['house', 'hello', 'hum', 'home'])