【问题标题】:Grouping strings from a set to a dictionary python将字符串从集合分组到字典python
【发布时间】:2016-11-16 17:39:12
【问题描述】:

输入:

>>> foo = {("A", "B"), ("A", "G"), ("A", "H"),
...         ("B", "C"), ("B", "H"),
...         ("C", "D"),
...         ("D", "E"), ("D", "G"), ("D", "H"),
...         ("E", "F"), ("E", "G"), ("E", "H"),
...         ("F", "I"), ("F", "J"), ("F", "K"),
...         ("G", "H")}

我正在尝试像这样对我的集合进行分组,到目前为止我一直没有成功,我设法只像这样对它们进行分组。

实际输出:

>>> {k:set(x[1] for x in v) for k,v in itertools.groupby(sorted(foo), key=lambda x: x[0])}
{'B': {'C', 'H'}, 'E': {'H', 'G', 'F'}, 'D': {'E', 'G', 'H'}, 'A': {'B', 'G', 'H'}, 'C': {'D'}, 'G': {'H'}, 'F': {'I', 'K', 'J'}}

不过,这是我的想要的输出

foo1  = {"A": {"B", "G", "H"},
         "B": {"A", "H", "C"},
         "C": {"B", "D"},
         "D": {"C", "E", "G", "H"},
         "E": {"D", "F", "G", "H"},
         "F": {"E", "I", "J", "K"},
         "G": {"A", "D", "E", "H"},
         "H": {"A", "B", "D", "E", "G"},
         "I": {"F"},
         "J": {"F"},
         "K": {"F"}
         }

我在考虑排列或组合?但我仍然不知道该怎么做。 提前致谢。 编辑:添加了字符串如何相关的图片。

【问题讨论】:

  • 您想确定字符串的分组方式是什么?编辑:等等,我想我明白了,但也请把这个放在问题中
  • 鉴于 Python set 和 dict 本质上是无序的,您是否期望输出有特定的顺序?
  • 您的排序字典理解确实排序正确,但它没有以您想要的方式打印给您?编辑:nvm,我在你得到的那个中看到了一些错误
  • 如果您正在使用图表,请查看 NetworkX。
  • 请不要破坏您的帖子

标签: python python-3.x dictionary set permutation


【解决方案1】:

这样的?

foo = {("A", "B"), ("A", "G"), ("A", "H"), ("B", "C"), ("B", "H"), ("C", "D"), ("D", "E"), ("D", "G"), ("D", "H"), ("E", "F"), ("E", "G"), ("E", "H"), ("F", "I"), ("F", "J"), ("F", "K"), ("G", "H")}

from collections import defaultdict

result = defaultdict(set)

for key1, key2 in foo:
    result[key1].add(key2)
    result[key2].add(key1)

from pprint import pprint
pprint(result)

与迄今为止的其他答案相反,它产生了所需的输出,尽管是无序的:

{'A': {'B', 'G', 'H'},
'B': {'A', 'C', 'H'},
'C': {'B', 'D'},
'D': {'G', 'C', 'H', 'E'},
'E': {'G', 'D', 'H', 'F'},
'F': {'I', 'J', 'K', 'E'},
'G': {'A', 'D', 'H', 'E'},
'H': {'B', 'A', 'G', 'D', 'E'},
'I': {'F'},
'J': {'F'},
'K': {'F'}}

【讨论】:

【解决方案2】:

OP 要求在理解的情况下完成此操作,所以这里有一个无偿的:

(请,请不要这样做)

python3
Python 3.5.2+ (default, Sep 22 2016, 12:18:14) 
[GCC 6.2.0 20160927] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import itertools
>>> import pprint
>>> 
>>> foo = {("A", "B"), ("A", "G"), ("A", "H"),
...         ("B", "C"), ("B", "H"),
...         ("C", "D"),
...         ("D", "E"), ("D", "G"), ("D", "H"),
...         ("E", "F"), ("E", "G"), ("E", "H"),
...         ("F", "I"), ("F", "J"), ("F", "K"),
...         ("G", "H")}
>>> 
>>> foo1 = {k: {x[1] for x in v} for k, v in itertools.groupby(sorted(foo | {(a, b) for b, a in foo}), key=lambda x: x[0])}
>>> pprint.pprint(foo1)
{'A': {'H', 'B', 'G'},
 'B': {'C', 'H', 'A'},
 'C': {'D', 'B'},
 'D': {'C', 'E', 'H', 'G'},
 'E': {'D', 'H', 'F', 'G'},
 'F': {'K', 'J', 'E', 'I'},
 'G': {'D', 'E', 'H', 'A'},
 'H': {'D', 'E', 'B', 'G', 'A'},
 'I': {'F'},
 'J': {'F'},
 'K': {'F'}}

【讨论】:

  • {(k, v) for k in foo1 for v in foo1[k]}
  • @PatrickHaugh:替换的是什么?无论它要替换什么,将其替换为{(k, v) for k, vs in foo1.items() for v in vs} 会更好一些;为每个键保存一个冗余查找,但我不确定它的目的是什么。
  • @ShadowRanger OP 要求从字典中取回他们的原始列表,但随后删除了他们的评论。
  • @PatrickHaugh:啊,有道理。但是,该集合理解实际上不会恢复原始的set;原来的set 被去重,这样每对的第一个元素总是小于每对的第二个元素(所以你会看到A, B 而不是B, A)。如果您想保留该不变量,您需要:{(k, v) for k, vs in foo1.items() for v in vs if k < v},以过滤掉重复的关联。
  • @ShadowRanger 我意识到了这一点,但没有注意到原始数据是如何排序的。关注<
【解决方案3】:

您可以使用普通字典,但defaultdict 会使这更容易一些。

from collections import defaultdict

d=defaultdict(set)
for key, value in foo:
    f[key].add(value)

使用常规字典:

d = {}
for key, value in foo:
    if key not in d:
        d[key]=set()
    d[key].add(value)

【讨论】:

  • 为了记录,虽然创建空集并丢弃它们会浪费时间,但您可以通过删除成员资格测试并将常规 dict 案例从三个 dict 查找简化为一个:@987654325 @、foo1.setdefault(key, set()).add(value)foo1.setdefault(value, set()).add(key)。或者为了避免 set 调用的开销,在 Py 3.5 及更高版本中,使用独眼猴子运算符(由我命名)通过语法而不是构造函数调用来创建一个空集:foo1.setdefault(key, {*()}).add(value)。 :-)
猜你喜欢
  • 2011-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 2019-09-26
  • 1970-01-01
相关资源
最近更新 更多