如何在 Python3 中使用不同种类的排列?
How can I use different kinds of permutations in Python3?
正常的排列是:
'ABC'
↓
'ACB'
'BAC'
'BCA'
'CAB'
'CBA'
但是,如果我想这样做怎么办:
'ABC'
↓
'AA'
'AB'
'AC'
'BA'
'BB'
'BC'
'CA'
'CB'
'CC'
这叫做什么,对于包含数百个元素的数组来说效率如何?
您的术语有点令人困惑:您拥有的不是字符的排列,而是每个可能字符与每个可能字符的配对:笛卡尔积。
您可以使用 itertools.product
生成这些组合,但请注意,此 returns 是迭代器而不是容器。所以如果你需要一个列表中的所有组合,你需要显式构造一个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']
如其所说Andras Deak, using itertools product:
import itertools
for i, j in itertools.product('ABC', repeat=2):
print(i + j)
不反对 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
您需要使用 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。 numberToBase
由 this post
提供
正常的排列是:
'ABC'
↓
'ACB'
'BAC'
'BCA'
'CAB'
'CBA'
但是,如果我想这样做怎么办:
'ABC'
↓
'AA'
'AB'
'AC'
'BA'
'BB'
'BC'
'CA'
'CB'
'CC'
这叫做什么,对于包含数百个元素的数组来说效率如何?
您的术语有点令人困惑:您拥有的不是字符的排列,而是每个可能字符与每个可能字符的配对:笛卡尔积。
您可以使用 itertools.product
生成这些组合,但请注意,此 returns 是迭代器而不是容器。所以如果你需要一个列表中的所有组合,你需要显式构造一个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']
如其所说Andras Deak, using itertools product:
import itertools
for i, j in itertools.product('ABC', repeat=2):
print(i + j)
不反对 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
您需要使用 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。 numberToBase
由 this post