Существует ли способ отобразить список на словарь? То, что я хочу сделать, дают ему функцию, которая возвратит название ключа, и значение будет исходным значением. Например;
somefunction(lambda a: a[0], ["hello", "world"])
=> {"h":"hello", "w":"world"}
(Это не определенный пример, который я хочу сделать, я хочу родовую функцию как map()
это может сделать это),
Не думаю, что существует стандартная функция, которая делает именно это, но построить ее с помощью dict builtin и понимания:
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 with a good name for this function is more difficult than implementation it. Оставлю это как упражнение для читателя.
На 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)
Если вы хотите, чтобы это сделала общая функция, то вы задаете почти правильный вопрос. Однако в вашем примере не указано, что происходит, когда ключевая функция производит дубликаты. Вы сохраняете последнюю? Первую? Вы действительно хотите составить список всех слов, которые начинаются с одной и той же буквы? На эти вопросы, наверное, лучше всего отвечать пользователю функции, а не дизайнеру.
Параметризируя эти результаты, вы получаете более сложную, но очень общую функцию. Вот одна, которую я использовал несколько лет:
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_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)
>>> 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'}
Наконец, если вы хотите использовать более одного слова на букву как возможность, используйте collection.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'])