#python #split #combinations
Вопрос:
Я хочу из строки построить пары, содержащие все возможные комбинации символов строки.
# Exemple :
s = "ABCD"
# Desired result :
["A", "BCD"]
["B", "ACD"]
["C", "ABD"]
...
["AB", "CD"]
...
["BC", "AD"]
...
["ABC", "D"]
["ABD", "C"]
["ACD", "B"]
["BCD", "A"]
Ответ №1:
Один из способов состоит в том, чтобы создавать комбинации индексов, а не самих элементов с увеличением r
: 1, 2,.., длина — 1. Затем мы находим оставшиеся индексы после выбора комбинации. itemgetter
можно получить значения, заданные индексами, и мы можем собрать их в список в виде строк:
from itertools import combinations
from operator import itemgetter
# given string and range till its length
s = "ABCD"
rng = range(len(s))
result = []
# for each combination possibility r...
for r in range(1, len(s)):
# get the indices from `rng`
for inds in combinations(rng, r):
# find `others` that are not `inds` in `rng`
others = [ind for ind in rng if ind not in inds]
# now index into the string with these indices to find pairs
first = itemgetter(*inds)(s)
second = itemgetter(*others)(s)
# store the stringifed pair
result.append(["".join(first), "".join(second)])
что дает
>>> result
[["A", "BCD"],
["B", "ACD"],
["C", "ABD"],
["D", "ABC"],
["AB", "CD"],
["AC", "BD"],
["AD", "BC"],
["BC", "AD"],
["BD", "AC"],
["CD", "AB"],
["ABC", "D"],
["ABD", "C"],
["ACD", "B"],
["BCD", "A"]]
Ответ №2:
Вы можете использовать двоичное представление числа с n двоичными цифрами: Ноль означает, что соответствующий символ должен идти влево, а единица-что он должен идти вправо:
def pairs(s):
for mask in range(1, 2**len(s) - 1):
pair = ["", ""]
for i, ch in enumerate(s):
pair[(mask >> i) amp; 1] = ch
yield pair
Пример использования:
print(list(pairs("ABCD"))
Ответ №3:
Не уверен, что это соответствует вашим потребностям, но more_ittools.set_partitions может быть решением.
from more_itertools import set_partitions
iterable = 'abcd'
for part in set_partitions(iterable, k=2):
print([''.join(p) for p in part])
С принтами:
['a', 'bcd']
['ab', 'cd']
['b', 'acd']
['abc', 'd']
['bc', 'ad']
['ac', 'bd']
['c', 'abd']
Ответ №4:
Вы можете использовать рекурсивную функцию генератора:
def pairs(d, c = []):
if not d and len(c) == 2:
yield c
elif d:
for i, a in enumerate(d):
if not c or len(c) == 1:
yield from pairs(d[:i] d[i 1:], c [a])
if c:
yield from pairs(d[:i] d[i 1:], c[:-1] [c[-1] a])
print(list(pairs('ABCD')))
Выход:
[['A', 'BCD'], ['A', 'BDC'], ['AB', 'CD'], ['ABC', 'D'], ['AB', 'DC'], ['ABD', 'C'], ['A', 'CBD'], ['A', 'CDB'], ['AC', 'BD'], ['ACB', 'D'], ['AC', 'DB'], ['ACD', 'B'], ['A', 'DBC'], ['A', 'DCB'], ['AD', 'BC'], ['ADB', 'C'], ['AD', 'CB'], ['ADC', 'B'], ['B', 'ACD'], ['B', 'ADC'], ['BA', 'CD'], ['BAC', 'D'], ['BA', 'DC'], ['BAD', 'C'], ['B', 'CAD'], ['B', 'CDA'], ['BC', 'AD'], ['BCA', 'D'], ['BC', 'DA'], ['BCD', 'A'], ['B', 'DAC'], ['B', 'DCA'], ['BD', 'AC'], ['BDA', 'C'], ['BD', 'CA'], ['BDC', 'A'], ['C', 'ABD'], ['C', 'ADB'], ['CA', 'BD'], ['CAB', 'D'], ['CA', 'DB'], ['CAD', 'B'], ['C', 'BAD'], ['C', 'BDA'], ['CB', 'AD'], ['CBA', 'D'], ['CB', 'DA'], ['CBD', 'A'], ['C', 'DAB'], ['C', 'DBA'], ['CD', 'AB'], ['CDA', 'B'], ['CD', 'BA'], ['CDB', 'A'], ['D', 'ABC'], ['D', 'ACB'], ['DA', 'BC'], ['DAB', 'C'], ['DA', 'CB'], ['DAC', 'B'], ['D', 'BAC'], ['D', 'BCA'], ['DB', 'AC'], ['DBA', 'C'], ['DB', 'CA'], ['DBC', 'A'], ['D', 'CAB'], ['D', 'CBA'], ['DC', 'AB'], ['DCA', 'B'], ['DC', 'BA'], ['DCB', 'A']]