如何创建一个有效限制特定字符的排列?

时间:2015-05-18 11:03:44

标签: python itertools

让你知道我在说什么。这是我现在的代码:

chrs = 'ABCDEF1234567890'
with open('two.txt', 'w') as two:
    for xs in itertools.product(chrs, repeat=10):
        h = sum(x.isalpha() for x in xs)
        if h == 2: two.write(''.join(xs) + '\n')

不幸的是,这需要几天时间,因为它会创建所有可能的组合,其中大多数组合不匹配。

编辑:为了澄清,我需要一种方法来找到变量 chrs 的所有可能组合,其中只有两个字母('ABCDEF')。无需创建所有组合的完整列表并检查每个组合。我需要创建其中包含两个字母的那些。

更进一步:

'AA12345678' = Good
'1234A123A4' = Good
'AAA1234567' = Bad
'A123456789' = Bad

我真的不知道我能解释多少5行python代码。

3 个答案:

答案 0 :(得分:2)

这是基于stars and bars而不是组合和排列。

从标准的星条和条形算法开始,对my previous work进行细化:

class SomeClass {
    /* modifiers */ aMethod(){
         /* an implementation */
    }
}

class SubClass extends SomeClass {
   /* if I don't reimplement aMethod() here, I get a compiler error */
}

验证它是否有效:

def stars_and_bars(star='*', bar='|', star_count=8, bar_count=2):
    if star_count == 0:
        yield (bar,) * bar_count
        return
    if bar_count == 0:
        yield (star,) * star_count
        return
    for left in range(star_count + 1):
        right = star_count - left
        assert right >= 0
        assert left + right == star_count
        for partial in stars_and_bars(star, bar, left, bar_count - 1):
            yield partial + (bar,) + (star,) * right

正如您所看到的,这会产生每种可能的星形和条形排列。有了8颗星和两个条形,我们可以用它来找到所有可能的数字和字母排列。然后我们将其传递给>>> sandb = stars_and_bars(star_count=3, bar_count=2) >>> for result in sandb: ... print(''.join(result)) ... ||*** |*|** *||** |**|* *|*|* **||* |***| *|**| **|*| ***||

itertools.product()

结果将是OP所要求的。

答案 1 :(得分:0)

嗯,它只是从0x0到0x10000000000的十六进制数字。不幸的是,这是~1.57e13的十进制,所以如果每个字符是1个字节,每个字符串是10个字符,没有过滤你的two.txt将是175TB的大小。

一旦你想到这一点,应该有一些方法可以通过一些简单的模数操作快速剔除列表中的大片,这将是我要走的路。

答案 2 :(得分:0)

我已the second answerKevin投了Oracle, Make date time's first day of its month,但我仍然觉得他的stars_and_bars实施有点过头了......这是我的看法在它

OH MY,复制和粘贴错误......一次肠胃切除下行... <击>

<击>
$ cat starbar.py
from itertools import combinations as _ic_
def sb(s, ns, b, nb):
    l = list(range(nb+ns) ---------------V
    return ([b if i in k else s for i in l)]for k in _ic_(l, nb))

<击> 现在这是正确的版本

$ cat starbar.py
from itertools import combinations as _ic_
def sb(s, ns, b, nb):
    l = list(range(nb+ns))
    return ([b if i in k else s for i in l] for k in _ic_(l, nb))

或者,如果您更喜欢详细的名称,

from itertools import combinations
def stars_and_bars(star, number_of_stars, bar, number_of_bars):
    possible_positions = list(range(number_of_bars + number_of_stars))
    return ([bar if i in combination else star for i in l]
            for combination in combinations(possible_positions, number_of_bars))

它是如何工作的?要解决这些问题,请说ns, nb = 2, 3并查看itertools.combination

所做的工作
>>> list(itertools.combinations(range(ns+nb),nb))
[(0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

你有[0,1,2,3,4]中3个不同数字的所有可能有序选项的迭代,此时很容易返回包含正确序列的星数的列表和酒吧

>>> from starbar import sb
>>> for s_b in sb('*',2, '|',3): print ''.join(s_b)
...
|||**
||*|*
||**|
|*||*
|*|*|
|**||
*|||*
*||*|
*|*||
**|||
>>>