在排列列表创建过程中排除值

时间:2019-01-04 20:32:34

标签: python permutation

我知道在Python中,我可以使用permutations()函数轻松地创建一个包含给定字符串的所有排列的列表。现在想象一下,如果我只想生成不包含字符串"3212323"的字符串"33"的排列。如何获得此结果?

示例:

  • “ 3231322”
  • “ 3332122” <-我不要你
  • “ 3213223”
  • “ 3223213”
  • “ 2223313” <-我不要你
  • “ 2322313”
  • “ 2312332” <-我不要你
  • ecc ...

注意:我知道我可以先生成所有排列,然后从列表中删除指定的排列,但是我需要的是根本不生成这些排列,因此在丢弃它们时创建排列列表。

任何建议将不胜感激。预先感谢。

4 个答案:

答案 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)))