在Python中生成n长度位列表

时间:2013-03-23 03:09:15

标签: python permutation bit

我想要一个函数,它将为我提供指定长度的所有可能的字符串,这些字符串仅由零和1组成。例如:

spam(4)

应该让我:

['0110', '0111', '0001', '0011', '0010', '0101', '0100', '1110', '1100', '1101', '1010', '1011', '1001', '1000']

我尝试使用itertools.permutations来完成这项工作。所以,这就是我所做的。

def getPerms(n):
    perms = getCandidates(n)
    res = []
    for i in perms:
        res.extend(permutations(i))
    res = clean(res)
    return res

def clean(ar):
    res = []
    for i in ar:
        temp = ""
        for j in i:
            temp += j
        res.append(temp)
    return list(set(res))

def getCandidates(n):
    res = []
    for i in range(1, n):
        res.append("1"*i + "0"*(n-i))
    return res

但这非常低效,并且在10上输入内存错误。

4 个答案:

答案 0 :(得分:8)

改为使用itertools.product

>>> import itertools
>>> [''.join(i) for i in itertools.product('01', repeat=4)]
['0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111']

使用函数(假设已导入itertools):

def bitGen(n):
    return [''.join(i) for i in itertools.product('01', repeat=n)]

对于较大的n s,返回生成器可能更合适。

def bitGen(n):
    return (''.join(i) for i in itertools.product('01', repeat=n))

# Alternatively:

def bitGen(n):
    for i in itertools.product('01', repeat=n):
        yield ''.join(i)

答案 1 :(得分:7)

你只是想生成位串,显然。这是我所知道的最快的方式:

for i in xrange(1, 2**n-1):
    yield '{:0{n}b}'.format(i, n=n)

这将生成长度恰好为n的每个位串,其中包含至少一个1和一个0。

示例:

>>> def gen(n):
...     for i in xrange(1, 2**n-1):
...         yield '{:0{n}b}'.format(i, n=n)
... 
>>> list(gen(4))
['0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110']

答案 2 :(得分:0)

除了上面的优秀答案之外,如果您想继续沿着您开始的路径前进,使用yield这是一个更好的实现:

from itertools import permutations

def spam(n):
    for perm in getPerms(n):
        print perm,
    print

def getPerms(n):
    for i in getCandidates(n):
        for perm in set(permutations(i)):
            yield ''.join(perm)

def getCandidates(n):
    for i in range(1, n):
        res = "1" * i + "0" * (n - i)
        yield res

spam(4)

答案 3 :(得分:0)

或者您可以使用递归..这具有能够生成任何n位k基数的附加优势

def bitStr(numDig, base):
 if numDig == 0: return []
 if numDig == 1: return [str(i) for i in range(0,base)]   
 return [ digit + bits for digit in bitStr(1, base)for bits in bitStr(numDig - 1, base)]

print(bitStr(4,2))