Создание словаря с наборами и значениями - PullRequest
0 голосов
/ 19 октября 2011

У меня есть следующие списки:

keys = ['god', 'hel', 'helo']
values = ['good','god', 'hell', 'hello']

Я хочу создать словарь, подобный этому:

{'god':set(['god', 'good']), 'hel':'hell', 'helo': 'hello'}

, где ключ определяется путем уменьшения повторяющихся букв в значении доодна буква.

Как бы я сделал это программно?

Ответы [ 3 ]

3 голосов
/ 19 октября 2011

"все повторяющиеся буквы уменьшены до отдельных букв"

На самом деле согласно этому правилу вам не нужен список keys, поскольку он будет создан из values.

Также я бы предложил использовать набор множеств для всех значений, в том числе для единичных, таких как «ад» и «привет».Это упростит использование словаря намного :

import itertools as it
values = ['good','god', 'hell', 'hello'] 
d = {}
for value in values:
    d.setdefault(''.join(k for k,v in it.groupby(value)), set()).add(value)

# d == {'god': set(['god', 'good']),
#       'hel': set(['hell']),
#       'helo': set(['hello'])}
1 голос
/ 19 октября 2011

Это должно сделать это для вас:

import re
import collections

values = ['good', 'god', 'hell', 'hello']
result = collections.defaultdict(set)
for value in values:
    key = re.sub(r'(\w)\1*', r'\1', value)
    result[key].add(value)

# result: defaultdict(<type 'set'>, {'hel': set(['hell']), 'god': set(['god', 'good']), 'helo': set(['hello'])})

# if you want to ensure that all your keys exist in the dictionary
keys = ['god', 'hel', 'helo', 'bob']
for key in keys:
    result[key]

# result: defaultdict(<type 'set'>, {'hel': set(['hell']), 'god': set(['god', 'good']), 'helo': set(['hello']), 'bob': set([])})
0 голосов
/ 19 октября 2011

Некоторый кодовый гольф (вроде - очевидно, что возможно больше запутывания) после ответа eumiro, отметив, что itertools.groupby можно использовать дважды (один раз, чтобы получить наборы букв в порядке появления, что-то, о чем я не думал - и снова, чтобы фактически создать пары ключ-значение для словаря).

from itertools import groupby
data = ['good', 'god', 'hell', 'hello']
dict((''.join(k), list(v)) for k, v in groupby(data, lambda x: zip(*groupby(x))[0]))

Как это работает: каждое слово сначала обрабатывается с помощью lambda x: zip(*groupby(x))[0]. То есть мы берем список пар (буква, группировщик-объект), созданных генератором groupby, преобразуем его в пару (списки букв, список-группировщиков-объектов) (содержимое генератора неявно оценивается для передачи в zip) и отбрасывает объекты list-grouper, которые нам не нужны. Затем мы группируем весь список слов в соответствии со списком букв, созданным каждым словом, преобразуем список букв обратно в строку, оцениваем генераторы объекта группирования, чтобы получить соответствующие слова, и используем эти значения ключа пары для построения финала dict.

Редактировать: Я думаю, что сделать лямбду в ''.join шаге чище:

from itertools import groupby
data = ['good', 'god', 'hell', 'hello']
dict((k, list(v)) for k, v in groupby(data, lambda x: ''.join(zip(*groupby(x))[0])))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...