Python - 加快列表排列的生成(以及检查字典中是不是排列的过程)

Posted

技术标签:

【中文标题】Python - 加快列表排列的生成(以及检查字典中是不是排列的过程)【英文标题】:Python - Speed up generation of permutations of a list (and process of checking if permuations in Dict)Python - 加快列表排列的生成(以及检查字典中是否排列的过程) 【发布时间】:2010-09-22 05:55:51 【问题描述】:

我需要一种更快的方法来生成列表的所有排列,然后检查每个排列是否都在字典中。

        for x in range (max_combo_len, 0, -1):
            possible_combos = []
            permutations = list(itertools.permutations(bag,x))
            for item in permutations:
                possible_combos.append(" ".join(item))
            #then check to see if each possible combo is in a specific Dict

如果有帮助,这些列表都将是字符串列表。 ['如', '这个', '一个']

我的解决方案有效,但速度很慢。可能是我需要停止使用 Python,但我想我会先由你们专家运行它!

最好, 加里

【问题讨论】:

max_combo_lenbag 的长度是多少?此外,如果您在更大的范围内让我们了解这是为了什么,我们也许可以提供更多帮助。 一方面,如果您要使用 for 循环对其进行迭代,则无需将 permutations 转换为列表。 谢谢。 max_combo_len 不会超过 4 或 5。bag 的长度是标准句子的长度。 Bag 本质上是一个单词列表 ['such', 'as', 'this', 'one'],我想在其中创建该列表的所有可能组合。 您所说的特定字典是什么意思?每个大小一个字典还是一个字典? 到目前为止的建议可能会有所帮助,但它们不会改变复杂性;如果速度太慢,那可能不是您想要的。请包含用于生成真实数量的实际测试数据的代码、使用它的自包含基准测试函数以及系统基准测试,以显示您看到的性能以及您希望改进的程度。 【参考方案1】:

一个非常基本的优化:

permutations = list(itertools.permutations(bag,x))
for item in permutations:

可以变成……

for item in itertools.permutations(bag,x):

【讨论】:

即,您不需要先将其转换为列表。【参考方案2】:

如果没有更好的输入用例,我无法很好地测试它,但这里有一些改进:

for x in xrange(max_combo_len, 0, -1):
    possible_combos = (" ".join(item) for item in itertools.permutations(bag,x))
    #then check to see if each possible combo is in a specific Dict
    combos =  (c for c in possible_combos if c in specific_dict)

首先,假设您使用的是 Python 2.x,xrange 将通过不构造显式列表来提供帮助,而只是根据需要生成每个 x

更重要的是,您可以将主要精力投入到生成器表达式中,并让它按需产生值。

【讨论】:

【参考方案3】:
    for x in xrange(max_combo_len, 0, -1):
        for item in itertools.permutations(bag,x):
            combo = " ".join(item)
            if combo in specificDict:
                yield combo

这样你就没有任何大的(越来越大的)列表,你只需要从函数中产生传递的组合。

【讨论】:

【参考方案4】:

如果您准备好您的特殊字典,您可以摆脱许多无用(丢弃)的连接操作:只需拆分值或键,具体取决于您比较的内容。这当然假设字典小于所有组合的数量。

如果你需要加入,你必须稍微改变一下。我认为如果您没有更具描述性,那么问题没有比这更好的可优化性了。使用另一种语言也不会快得多。


(filtered_combo for filtered_combo in      
        itertools.chain.from_iterable(
                combo for combo in (itertools.permutations(bag, x) 
                        for x in xrange(max_combo_len, 0, -1)))
        if filtered_combo in special_dict)

【讨论】:

【参考方案5】:

这样的?

sentences = ['such as', 'this', 'ten eggs', 'one book', 'six eggs']
bag_of_words = set(['such', 'one','ten','book','eggs'])

possible = [sentence
            for sentence in sentences
            if all(word in bag_of_words for word in sentence.split())
            ]

print 'Possible to produce from bag words are:\n\t%s' % '\n\t'.join(possible)

【讨论】:

OP 看起来想检查单词组合是否可以从单词词典中产生,所以我想“跳出框框思考”,与他似乎正在尝试的相反。这消除了程序的指数(阶乘?)复杂性。

以上是关于Python - 加快列表排列的生成(以及检查字典中是不是排列的过程)的主要内容,如果未能解决你的问题,请参考以下文章

将 Python 字典排列组合到字典列表中

python 复杂的列表排列成字典

如何优化拼字游戏中的单词排列?

Python面试必考重点之列表,元组和字典第十二关——如果列表元素是字典序列,如何利用lambda表达式对列表进行升序降序排列

Python面试必考重点之列表,元组和字典第四关——编写一个函数(不要使用python模块的函数),打乱列表元素的顺序/如何对列表元素进行随机排列

如何检查字典值是不是在 python 的字典列表中可用?