用集合和值创建字典

-1 投票
3 回答
3447 浏览
提问于 2025-04-17 04:36

我有以下这些列表:

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

我想创建一个字典,像这样:

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

在这个字典中,键是通过把值中重复的字母简化成一个字母来决定的。

我该怎么用程序来实现这个呢?

3 个回答

0

这段代码有点像是代码高尔夫(就是尽量把代码写得短小精悍),是基于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的时候会被自动计算),接着我们丢掉不需要的分组对象列表。然后,我们根据每个单词生成的字母列表对整个单词列表进行分组,再把字母列表转回字符串,计算分组对象生成器以获取对应的单词,最后用这些键值对来构建最终的 dict

补充一下:我觉得把 ''.join 的步骤放在lambda里会更简洁:

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])))
1

这段代码应该能帮到你:

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([])})
3

"所有重复的字母都变成单个字母"

其实根据这个规则,你不需要 keys 列表,因为它会从 values 中自动生成。

我还建议对所有的值,包括像 "hell" 和 "hello" 这样的单个值,使用一个集合字典,这样使用字典会简单得多:

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'])}

撰写回答