Как уменьшить наборы значений dict, используя понимание?

У меня есть

x = {'a':set([1]) , 'b':set([2]), 'c':set([3]) }

Гарантируется, что в множестве есть только один элемент. Мне нужно преобразовать это в

{'a': 1, 'c': 3, 'b': 2}

Следующие работы:

x1 = {k:x[k].pop() for k in x.keys()}  OR
x1 = {k:next(iter(x[k])) for k in x.keys()}

но мне это не нравится, так как pop() здесь модифицирует исходную коллекцию. Мне нужна помощь в следующем.

  • Как я могу использовать распаковку, как здесь в пределах понимания.
  • Есть ли способ, я могу использовать functools.reduce для этого.
  • Что может быть лучшим или питоническим способом сделать это в целом?

person ViFI    schedule 24.05.2017    source источник
comment
functools.reduce практически не имеет ничего общего с операцией, которую вы пытаетесь выполнить.   -  person user2357112 supports Monica    schedule 25.05.2017


Ответы (2)


Если вы хотите сделать это с помощью распаковки, это будет

{k: item for k, [item] in x.iteritems()}
person user2357112 supports Monica    schedule 24.05.2017
comment
Это создаст AttributeError внутри Python 3.5.2. - person Chiheb Nexus; 25.05.2017
comment
@ChihebNexus: действительно будет, но вопрос помечен 2.7. - person user2357112 supports Monica; 25.05.2017
comment
Спасибо за это. Это то, что я хотел. Просто упомянем, что распаковка также выполняет проверку того, что в наборе есть только один элемент, что и имеет место здесь. распаковка элементов с более чем одним элементом даст ошибку. - person ViFI; 25.05.2017
comment
{k: item for k, [item] in x.items()} был бы способом сделать это, кто-то ищет версию, совместимую с Python 2, а также с 3. items неэффективен в Python 2, но для небольших списков не должен иметь большого значения. - person ViFI; 25.05.2017

На мой взгляд, наиболее читаемым вариантом было бы использование next и iter. Распаковка также может быть бесполезна, так как это скорее операция присваивания. (см. ответ пользователя 2357112)

Как насчет просто:

>>> {k: next(iter(v)) for k, v in x.items()}
{'a': 1, 'c': 3, 'b': 2}
person UltraInstinct    schedule 24.05.2017