【问题标题】:Python: How to get possible combinations of keys in dictPython:如何在 dict 中获取可能的键组合
【发布时间】:2018-10-22 15:49:46
【问题描述】:

给定一个词汇表:{'A': 3, 'B': 4, 'C': 5, 'AB':6} 和一个应分段的句子:ABCAB

我需要创建这句话的所有可能组合,例如 [['A', 'B', 'C', 'A', 'B'], ['A', 'B', 'C', 'AB'], ['AB', 'C', 'AB'], ['AB', 'C', 'A', 'B']]

这就是我所拥有的:

def find_words(sentence):   
    for i in range(len(sentence)):

        for word_length in range(1, max_word_length + 1):

            word = sentence[i:i+word_length]
            print(word)

            if word not in test_dict:
                continue

            if i + word_length <= len(sentence):
                if word.startswith(sentence[0]) and word not in words and word not in ''.join(words):
                    words.append(word)
                else:
                    continue

                next_position = i + word_length

                if next_position >= len(sentence):
                    continue
                else:
                    find_ngrams(sentence[next_position:])

    return words

但它只返回一个列表。

我也在 itertools 中寻找有用的东西,但我找不到任何明显有用的东西。不过可能错过了。

【问题讨论】:

  • 在您的示例中,| 是否表示逗号?
  • 我想我会分两个阶段进行。 1:尝试用工具中最小的元素完成给定的句子。 2:尝试将解决方案中的元素合并到更大的工具中。
  • @ninesalt 是的,它也可以是空格或类似的东西
  • 请用逗号代替竖线修正您的示例列表,并添加普通样式'
  • 词汇表中的数字有什么意义?

标签: python string python-3.x list text-segmentation


【解决方案1】:

尝试所有可能的前缀并递归地对句子的其余部分执行相同的操作。

VOC = {'A', 'B', 'C', 'AB'}  # could be a dict

def parse(snt):
    if snt == '': 
        yield []
    for w in VOC:
        if snt.startswith(w):
            for rest in parse(snt[len(w):]):
                yield [w] + rest

print(list(parse('ABCAB')))

# [['AB', 'C', 'AB'], ['AB', 'C', 'A', 'B'],
# ['A', 'B', 'C', 'AB'], ['A', 'B', 'C', 'A', 'B']]

【讨论】:

  • 我有一个新问题:我有一个巨大的字典 (6MB) 和数千个句子 (30MB) 应该被解析。您认为这种方法需要很长时间来处理吗?因为我昨天等了8个多小时,还没有完成。 @VPfB
  • @Y.River 一些优化肯定是可能的,但除此之外我不知道有什么不同的更有效的方法。我想建议测量几个平均句子的时间。然后您可以估计处理数千个句子所需的时间。您还可以添加某种计数器来监控进度。
  • 是的,我会试试的。谢谢你!
【解决方案2】:

虽然不是最有效的解决方案,但这应该可行:

from itertools import product

dic = {'A': 3, 'B': 4, 'C': 5, 'AB': 6}
choices = list(dic.keys())
prod = []

for a in range(1, len(choices)+2):
    prod = prod + list(product(choices, repeat=a))

result = list(filter(lambda x: ''.join(x) == ''.join(choices), prod))
print(result) 

# prints [('AB', 'C', 'AB'), ('A', 'B', 'C', 'AB'), ('AB', 'C', 'A', 'B'), ('A', 'B', 'C', 'A', 'B')]

【讨论】:

  • 谢谢,但我需要的是分句。该词典将非常庞大,并且仅提供仅使用其中一部分的不同单词。 @ninesalt
【解决方案3】:

使用 itertools 排列来给出所有唯一的组合。

d ={'A': 3, 'B': 4, 'C': 5, 'AB':6}

l = [k for k, v in d.items()]

print(list(itertools.permutations(l)))

[('A', 'B', 'C', 'AB'), ('A', 'B', 'AB', 'C'), ('A', 'C', 'B', 'AB'), ('A', 'C', 'AB', 'B'), ('A', 'AB', 'B', 'C'), ('A', 'AB', 'C', 'B'), ('B', 'A', 'C', 'AB'), ('B', 'A', 'AB', 'C'), ('B', 'C', 'A', 'AB'), ('B', 'C', 'AB', 'A'), ('B', 'AB', 'A', 'C'), ('B', 'AB', 'C', 'A'), ('C', 'A', 'B', 'AB'), ('C', 'A', 'AB', 'B'), ('C', 'B', 'A', 'AB'), ('C', 'B', 'AB', 'A'), ('C', 'AB', 'A', 'B'), ('C', 'AB', 'B', 'A'), ('AB', 'A', 'B', 'C'), ('AB', 'A', 'C', 'B'), ('AB', 'B', 'A', 'C'), ('AB', 'B', 'C', 'A'), ('AB', 'C', 'A', 'B'), ('AB', 'C', 'B', 'A')]

【讨论】:

  • OP 希望排列按特定顺序排列。
  • 你得到排列['A'|'B'|'C‘|‘A‘|‘B‘]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多