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_len
和bag
的长度是多少?此外,如果您在更大的范围内让我们了解这是为了什么,我们也许可以提供更多帮助。
一方面,如果您要使用 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面试必考重点之列表,元组和字典第十二关——如果列表元素是字典序列,如何利用lambda表达式对列表进行升序降序排列
Python面试必考重点之列表,元组和字典第四关——编写一个函数(不要使用python模块的函数),打乱列表元素的顺序/如何对列表元素进行随机排列