Список карты на словарь

Существует ли способ отобразить список на словарь? То, что я хочу сделать, дают ему функцию, которая возвратит название ключа, и значение будет исходным значением. Например;

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

(Это не определенный пример, который я хочу сделать, я хочу родовую функцию как map() это может сделать это),

25
задан Jeffrey Aylesworth 3 January 2010 в 03:18
поделиться

5 ответов

Не думаю, что существует стандартная функция, которая делает именно это, но построить ее с помощью 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. Оставлю это как упражнение для читателя.

27
ответ дан 28 November 2019 в 18:05
поделиться

На Python 3 вы можете использовать синтаксис понимания словаря:

def foo(somelist):
    return {x[0]:x for x in somelist}
37
ответ дан 28 November 2019 в 18:05
поделиться

Если я правильно понял ваш вопрос, то думаю, что вы можете это сделать с помощью комбинации 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)
5
ответ дан 28 November 2019 в 18:05
поделиться

Если вы хотите, чтобы это сделала общая функция, то вы задаете почти правильный вопрос. Однако в вашем примере не указано, что происходит, когда ключевая функция производит дубликаты. Вы сохраняете последнюю? Первую? Вы действительно хотите составить список всех слов, которые начинаются с одной и той же буквы? На эти вопросы, наверное, лучше всего отвечать пользователю функции, а не дизайнеру.

Параметризируя эти результаты, вы получаете более сложную, но очень общую функцию. Вот одна, которую я использовал несколько лет:

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)
1
ответ дан 28 November 2019 в 18:05
поделиться
>>> 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'])
1
ответ дан 28 November 2019 в 18:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: