尽管有很多算法和函数可以从一组唯一的项目中生成任意大小的独特组合,但对于包含重复值的列表(即包含重复值的列表),没有可用的算法和函数。
问题是如何在生成器函数中即时生成来自非唯一列表的所有独特组合,而无需计算昂贵的去重操作?
如果对于另一个组合comboB,两个组合的排序列表相同,则我认为组合comboA是独特的。让我们举一个检查此类唯一性的代码示例:
在上述示例中,B 是 A 的副本,print() 打印出 B 是 A 的副本。
解决非唯一列表情况下提供即时独特组合的生成器函数的问题在这里得到了解决:从一个非唯一项目列表中获取唯一组合,更快?,但提供的生成器函数需要查找并且需要内存,在大量组合的情况下会导致问题。
当前答案版本中提供的函数可以在不进行任何查找的情况下完成工作,并且似乎是正确的答案,但是……
摆脱查找的目标是为了加速在带有重复项的列表情况下生成唯一组合。
我最初(编写这个问题的第一个版本时)错误地假设代码不需要创建用于查找的集合,不需要确保独特性,会比需要查找的代码更有优势。事实并非如此。 至少不总是这样。迄今为止提供的答案中的代码没有使用查找,但在没有冗余列表或仅少量的冗余项目在列表中的情况下,生成所有组合需要更长的时间。
这里是一些时间来说明当前的情况:
以上时间表说明了两种极端情况:无重复和仅有重复。所有其他时间都介于这两者之间。
我对上述结果的解释是,一个纯粹的Python函数(不使用任何C编译模块)可以非常快,但也可能因列表中有多少个重复而变得更慢。因此,可能没有绕过编写C/C++代码来提供所需功能的Python .so扩展模块的方法。
问题是如何在生成器函数中即时生成来自非唯一列表的所有独特组合,而无需计算昂贵的去重操作?
如果对于另一个组合comboB,两个组合的排序列表相同,则我认为组合comboA是独特的。让我们举一个检查此类唯一性的代码示例:
comboA = [1,2,2]
comboB = [2,1,2]
print("B is a duplicate of A" if sorted(comboA)==sorted(comboB) else "A is unique compared to B")
在上述示例中,B 是 A 的副本,print() 打印出 B 是 A 的副本。
解决非唯一列表情况下提供即时独特组合的生成器函数的问题在这里得到了解决:从一个非唯一项目列表中获取唯一组合,更快?,但提供的生成器函数需要查找并且需要内存,在大量组合的情况下会导致问题。
当前答案版本中提供的函数可以在不进行任何查找的情况下完成工作,并且似乎是正确的答案,但是……
摆脱查找的目标是为了加速在带有重复项的列表情况下生成唯一组合。
我最初(编写这个问题的第一个版本时)错误地假设代码不需要创建用于查找的集合,不需要确保独特性,会比需要查找的代码更有优势。事实并非如此。 至少不总是这样。迄今为止提供的答案中的代码没有使用查找,但在没有冗余列表或仅少量的冗余项目在列表中的情况下,生成所有组合需要更长的时间。
这里是一些时间来说明当前的情况:
-----------------
k: 6 len(ls): 48
Combos Used Code Time
---------------------------------------------------------
12271512 len(list(combinations(ls,k))) : 2.036 seconds
12271512 len(list(subbags(ls,k))) : 50.540 seconds
12271512 len(list(uniqueCombinations(ls,k))) : 8.174 seconds
12271512 len(set(combinations(sorted(ls),k))): 7.233 seconds
---------------------------------------------------------
12271512 len(list(combinations(ls,k))) : 2.030 seconds
1 len(list(subbags(ls,k))) : 0.001 seconds
1 len(list(uniqueCombinations(ls,k))) : 3.619 seconds
1 len(set(combinations(sorted(ls),k))): 2.592 seconds
以上时间表说明了两种极端情况:无重复和仅有重复。所有其他时间都介于这两者之间。
我对上述结果的解释是,一个纯粹的Python函数(不使用任何C编译模块)可以非常快,但也可能因列表中有多少个重复而变得更慢。因此,可能没有绕过编写C/C++代码来提供所需功能的Python .so扩展模块的方法。