将列表映射到字典

时间:2010-01-03 03:18:14

标签: python list functional-programming hashtable

有没有办法将列表映射到字典?我想要做的是给它一个函数,它将返回一个键的名称,该值将是原始值。例如;

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

(这不是我想要做的具体示例,我想要一个像map()这样的通用函数可以做到这一点)

6 个答案:

答案 0 :(得分:35)

在Python 3中,您可以使用此词典理解语法:

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

答案 1 :(得分:27)

我不认为存在一个完全符合标准函数的标准函数,但使用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'}

但是为这个功能提出一个好名字比实现它更困难。我将把它作为读者的练习。

答案 2 :(得分:5)

如果我正确理解您的问题,我相信您可以结合mapzipdict构造函数来完成此任务:

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

更实用的实施:

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

答案 3 :(得分: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'])

取决于您是否要保留以“h”开头的第一个或最后一个单词。

这个函数非常通用,所以大部分时间它都是其他函数的基础,比如group_dicthistogram

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)

答案 4 :(得分:1)

>>> 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'}

最后,如果您希望每个字母有多个单词作为可能,请使用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'])

答案 5 :(得分:1)

从其他答案中获取提示我使用地图操作实现了这一点。我不确定这是否完全回答了你的问题。

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