如何在Python3中使用不同类型的排列?

时间:2016-12-20 01:31:23

标签: python permutation

正常的排列是:

'ABC'
  ↓
'ACB'
'BAC'
'BCA'
'CAB'
'CBA'

但是,如果我想这样做怎么办:

'ABC'
  ↓
'AA'
'AB'
'AC'
'BA'
'BB'
'BC'
'CA'
'CB'
'CC'

这是什么,以及具有数百个元素的数组的效率如何?

4 个答案:

答案 0 :(得分:2)

你的术语有点令人困惑:你所拥有的不是你角色的排列,而是每个可能的角色与每个可能的角色的搭配:笛卡尔积。

您可以使用itertools.product生成这些组合,但请注意,这会返回迭代器而不是容器。因此,如果您需要列表中的所有组合,则需要明确构造list

from itertools import product
mystr = 'ABC'
prodlen = 2
products = list(product(mystr,repeat=prodlen))

或者,如果你只是循环这些值:

for char1,char2 in product(mystr,repeat=prodlen):
    # do something with your characters
    ...

或者,如果要生成2长度字符串,可以在列表推导中执行此操作:

allpairs = [''.join(pairs) for pairs in products]
# ['AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC']

答案 1 :(得分:1)

对于itertools没有任何意义,但是如果您想通过将模运算应用于递增序列号来手动生成字符串的排列,则需要了解一些内容。应该使用任意长度的字符串以及n n <= len(s)

的任何值

生成的排列数为len(s) ** n

例如,只需致电printPermutations("abc", 2)

def printPermutations(s, n) :
    if (not s) or (n < 1):
        return
    maxpermutations = len(s) ** n
    for p in range(maxpermutations):
        perm = getSpecificPermutation(s, n, p)
        print(perm)

def getSpecificPermutation(s, n, p):
    # s is the source string
    # n is the number of characters to extract
    # p is the permutation sequence number
    result = ''
    for j in range(n):
        result = s[p % len(s)] + result
        p = p // len(s)
    return result

答案 2 :(得分:0)

正如Andras Deak所述,使用itertools product

import itertools

for i, j in itertools.product('ABC', repeat=2):
    print(i + j)

答案 3 :(得分:0)

您想要使用itertools解决方案。 但我知道它叫什么......

大多数人都称之为计数。你对此很狡猾,但我认为它只是计算在基数len(set),其中set是你的输入set(我假设它真的是一个集合,没有重复的元素)。想象一下,在你的例子中A -> 0, B->1, C->2。您还要求具有一定数量最大数字的元素。让我告诉你:

def numberToBase(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n /= b
    return digits[::-1]

def count_me(set, max_digits=2):
    # Just count! From 0 to len(set) ** max_digits to be precise
    numbers = [i for i in range(len(set) ** max_digits)]

    # Convert to base len(set)
    lists_of_digits_in_base_b = [numberToBase(i, len(set)) for i in numbers]

    # Add 0s to the front (making each list of digits max_digit - 1 in length)
    prepended_with_zeros = []
    for li in lists_of_digits_in_base_b:
        prepended_with_zeros.append([0]*(max_digits - len(li)) + li)

    # Map each digit to an item in our set
    m = {index: item for index, item in enumerate(set)}
    temp = map(lambda x: [m[digit] for digit in x], prepended_with_zeros)

    # Convert to strings
    temp2 = map(lambda x: [str(i) for i in x], prepended_with_zeros)

    # Concatenate each item
    concat_strings = map(lambda a: reduce(lambda x, y: x + y, a, ""), temp)

    return concat_strings

这里有一些输出:

print count_me("ABC", 2)

输出:

['AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC']

print count_me("ABCD", 2)

输出:

['AA', 'AB', 'AC', 'AD', 'BA', 'BB', 'BC', 'BD', 'CA', 'CB', 'CC', 'CD', 'DA', 'DB', 'DC', 'DD']

print count_me("ABCD", 3)

输出(一个大的):

['AAA', 'AAB', 'AAC', 'AAD', 'ABA', 'ABB', 'ABC', 'ABD', 'ACA', 'ACB', 'ACC', 'ACD', 'ADA', 'ADB', 'ADC', 'ADD', 'BAA', 'BAB', 'BAC', 'BAD', 'BBA', 'BBB', 'BBC', 'BBD', 'BCA', 'BCB', 'BCC', 'BCD', 'BDA', 'BDB', 'BDC', 'BDD', 'CAA', 'CAB', 'CAC', 'CAD', 'CBA', 'CBB', 'CBC', 'CBD', 'CCA', 'CCB', 'CCC', 'CCD', 'CDA', 'CDB', 'CDC', 'CDD', 'DAA', 'DAB', 'DAC', 'DAD', 'DBA', 'DBB', 'DBC', 'DBD', 'DCA', 'DCB', 'DCC', 'DCD', 'DDA', 'DDB', 'DDC', 'DDD']

P.S。 numberToBasethis post

提供onPause