我知道在Python中,我可以使用permutations()
函数轻松地创建一个包含给定字符串的所有排列的列表。现在想象一下,如果我只想生成不包含字符串"3212323"
的字符串"33"
的排列。如何获得此结果?
示例:
注意:我知道我可以先生成所有排列,然后从列表中删除指定的排列,但是我需要的是根本不生成这些排列,因此在丢弃它们时创建排列列表。
任何建议将不胜感激。预先感谢。
答案 0 :(得分:3)
使用自定义过滤器的解决方案
from itertools import permutations
a="3212323"
def my_filter(temp):
if '33' not in ''.join(temp):
return temp
filter(my_filter,(permutations(a)))
它是python,因此您可以查看源代码并对其进行修改
def permutations1(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = range(n)
cycles = range(n, n-r, -1)
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
temp=tuple(pool[i] for i in indices[:r])
if '33' not in ''.join(temp):
yield temp
break
else:
return
list((permutations1(a)))
答案 1 :(得分:1)
您可以使用生成器:
original = "3212323"
excluded_substring = '33'
p = (''.join(x) for x in permutations(original))
p = (x for x in p if excluded_substring not in x)
# Or as a one-liner
p = (x for x in (''.join(parts) for parts in permutations(original)) if excluded_substring not in x)
所有这些都是生成器,这样您就不会在内存中一次拥有所有可能的组合。如果要作为列表使用,只需将第二行(或单行最外)的括号更改为方括号。
答案 2 :(得分:1)
如果您查看permutations的文档,它们将为您提供功能的实质。您可以修改它以排除'33'
def permutations(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = list(range(n))
cycles = list(range(n, n-r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
seq = tuple(pool[i] for i in indices[:r])
# Check if '33' is in sequence
if '33' not in ''.join(seq):
yield seq
break
else:
return
答案 3 :(得分:1)
类似于第一个选项_mads,您还可以使用itertools中的filterfalse(predicate, iterable)函数:
from itertools import permutations, filterfalse
_str = "3212323"
def predicate(iterable):
return '33' in ''.join(iterable)
filterfalse(predicate, permutations(_str)))