Map list onto dictionary

删除回忆录丶 提交于 2019-12-31 17:54:34

问题


Is there a way to map a list onto a dictionary? What I want to do is give it a function that will return the name of a key, and the value will be the original value. For example;

somefunction(lambda a: a[0], ["hello", "world"])
=> {"h":"hello", "w":"world"}

(This isn't a specific example that I want to do, I want a generic function like map() that can do this)


回答1:


I don't think a standard function exists that does exactly that, but it's very easy to construct one using the dict builtin and a comprehension:

def somefunction(keyFunction, values):
    return dict((keyFunction(v), v) for v in values)

print somefunction(lambda a: a[0], ["hello", "world"])

Output:

{'h': 'hello', 'w': 'world'}

But coming up with a good name for this function is more difficult than implementing it. I'll leave that as an exercise for the reader.




回答2:


In Python 3 you can use this dictionary comprehension syntax:

def foo(somelist):
    return {x[0]:x for x in somelist}



回答3:


If I understand your question correctly, I believe you can accomplish this with a combination of map, zip, and the dict constructor:

def dictMap(f, xs) :
    return dict(zip(map(f, xs), xs)

And a saner implementation :

def dictMap(f, xs) :
    return dict((f(i), i) for i in xs)



回答4:


If you want a general function to do this, then you're asking almost the right question. Your example doesn't specify what happens when the key function produces duplicates, though. Do you keep the last one? The first one? Do you actually want to make a list of all the words that start with the same letter? These questions are probably best answered by the user of the function, not the designer.

Parametrizing over these results in a more complicated, but very general, function. Here's one that I've used for several years:

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

Then you can write your function by saying:

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'])

Depending on whether you want to keep the first or last word starting with, for example, 'h'.

This function is very general, though, so most of the time it's the basis for other functions, like group_dict or 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)



回答5:


>>> dict((a[0], a) for a in "hello world".split())
{'h': 'hello', 'w': 'world'}

If you want to use a function instead of subscripting, use operator.itemgetter:

>>> from operator import itemgetter
>>> first = itemgetter(0)
>>> dict((first(x), x) for x in "hello world".split())
{'h': 'hello', 'w': 'world'}

Or as a function:

>>> dpair = lambda x : (first(x), x)
>>> dict(dpair(x) for x in "hello world".split())
{'h': 'hello', 'w': 'world'}

Finally, if you want more than one word per letter as a possibility, use 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'])



回答6:


Taking hints from other answers I achieved this using map operation. I am not sure if this exactly answers your question.

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


来源:https://stackoverflow.com/questions/1993840/map-list-onto-dictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!