Python 带OR算子的Itertools置换
给定一个字符串列表,我想返回所有可能的排列,其中字符串可能包含OR运算符 我该怎么做?一个指针,指向我应该使用的函数对代码来说是可以的,这会很有帮助,但不是必需的 比如说,Python 带OR算子的Itertools置换,python,python-3.x,itertools,Python,Python 3.x,Itertools,给定一个字符串列表,我想返回所有可能的排列,其中字符串可能包含OR运算符 我该怎么做?一个指针,指向我应该使用的函数对代码来说是可以的,这会很有帮助,但不是必需的 比如说, #!/usr/bin/env python3 import itertools list_of_strings = ['a|b', 'c'] # I probably need to add some '|' splitter here for permutation in itertools.permutations
#!/usr/bin/env python3
import itertools
list_of_strings = ['a|b', 'c']
# I probably need to add some '|' splitter here
for permutation in itertools.permutations(list_of_strings, 2):
print(''.join(str(word) for word in permutation))
印刷品
a|bc
ca|b
但是我想要
ac
bc
ca
cb
也就是说,使用“a”或“b”,但不能同时使用两者
可能有多个带“|”的字符串。例如,list_of_string=['a | b','c','d | e']
一个字符串中可能有多个OR。例如,list_of_string=['a | b | d | e','c']
前面的示例应该打印出来
ac
bc
dc
ec
ca
cb
cd
ce
字符串可能长于一个字符。例如,list_of_string=['race','car | horse']
输出应该是
racecar
racehorse
carrace
horserace
解决方案分为两个阶段: 生成\u字符串列表\u的置换 递归解析or运算符 看一看,似乎通过了所有的测试用例,请随意在评论中要求澄清
import itertools
def permutations_with_ors(list_of_strings):
for item in itertools.permutations(list_of_strings):
yield from parse_ors(item)
def parse_ors(tuple_of_strings):
for i, string in enumerate(tuple_of_strings):
if '|' in string:
for item in string.split('|'):
replaced = (
tuple_of_strings[:i] +
(item,) +
tuple_of_strings[i + 1:]
)
yield from parse_ors(replaced)
break
else:
yield ''.join(tuple_of_strings)
list_of_strings = ['a|b', 'c']
for item in permutations_with_ors(list_of_strings):
print(item)
# output:
# ac
# bc
# ca
# cb
print()
list_of_strings = ['a|b|d|e', 'c']
for item in permutations_with_ors(list_of_strings):
print(item)
# output:
# ac
# bc
# dc
# ec
# ca
# cb
# cd
# ce
print()
list_of_strings = ['a|b', 'c', 'd|e']
for item in permutations_with_ors(list_of_strings):
print(item)
# output is quite long, please check it yourself
print()
list_of_strings = ['race', 'car|horse']
for item in permutations_with_ors(list_of_strings):
print(item)
# output:
# racecar
# racehorse
# carrace
# horserace
解决方案分为两个阶段: 生成\u字符串列表\u的置换 递归解析or运算符 看一看,似乎通过了所有的测试用例,请随意在评论中要求澄清
import itertools
def permutations_with_ors(list_of_strings):
for item in itertools.permutations(list_of_strings):
yield from parse_ors(item)
def parse_ors(tuple_of_strings):
for i, string in enumerate(tuple_of_strings):
if '|' in string:
for item in string.split('|'):
replaced = (
tuple_of_strings[:i] +
(item,) +
tuple_of_strings[i + 1:]
)
yield from parse_ors(replaced)
break
else:
yield ''.join(tuple_of_strings)
list_of_strings = ['a|b', 'c']
for item in permutations_with_ors(list_of_strings):
print(item)
# output:
# ac
# bc
# ca
# cb
print()
list_of_strings = ['a|b|d|e', 'c']
for item in permutations_with_ors(list_of_strings):
print(item)
# output:
# ac
# bc
# dc
# ec
# ca
# cb
# cd
# ce
print()
list_of_strings = ['a|b', 'c', 'd|e']
for item in permutations_with_ors(list_of_strings):
print(item)
# output is quite long, please check it yourself
print()
list_of_strings = ['race', 'car|horse']
for item in permutations_with_ors(list_of_strings):
print(item)
# output:
# racecar
# racehorse
# carrace
# horserace
这里只有几个步骤 在|上拆分每个原始字符串以获得字符串列表。 计算字符串列表的排列。 计算每个排列的乘积 用空字符串连接这些产品的每个元素。 使用itertools和operator模块,情况如下所示:
>>> from itertools import product, permutations
>>> from operator import methodcaller
>>> splitter = methodcaller("split", "|")
>>> list_of_strings = ["a|b", "c", "foo|bar"]
>>> strings = ["".join(y) for x in permutations(map(splitter, list_of_strings)) for y in product(*x)]
>>> for s in strings:
... print(s)
...
acfoo
acbar
bcfoo
bcbar
afooc
abarc
bfooc
bbarc
cafoo
cabar
cbfoo
cbbar
cfooa
cfoob
cbara
cbarb
fooac
foobc
barac
barbc
fooca
foocb
barca
barcb
更容易理解的是,长长的一行
strings = ["".join(y)
for x in permutations(map(splitter, list_of_strings))
for y in product(*x)]
如果您不像我通常那样倾向于使用map,那么可以去掉methodcaller,并使用生成器表达式作为置换的参数
这里只有几个步骤 在|上拆分每个原始字符串以获得字符串列表。 计算字符串列表的排列。 计算每个排列的乘积 用空字符串连接这些产品的每个元素。 使用itertools和operator模块,情况如下所示:
>>> from itertools import product, permutations
>>> from operator import methodcaller
>>> splitter = methodcaller("split", "|")
>>> list_of_strings = ["a|b", "c", "foo|bar"]
>>> strings = ["".join(y) for x in permutations(map(splitter, list_of_strings)) for y in product(*x)]
>>> for s in strings:
... print(s)
...
acfoo
acbar
bcfoo
bcbar
afooc
abarc
bfooc
bbarc
cafoo
cabar
cbfoo
cbbar
cfooa
cfoob
cbara
cbarb
fooac
foobc
barac
barbc
fooca
foocb
barca
barcb
更容易理解的是,长长的一行
strings = ["".join(y)
for x in permutations(map(splitter, list_of_strings))
for y in product(*x)]
如果您不像我通常那样倾向于使用map,那么可以去掉methodcaller,并使用生成器表达式作为置换的参数
有一个答案是,用词,但给出重复的结果。def perms,n=2:对于itertools.product中的p*[k.split |对于s中的k]:来自itertools.permutationsp的产量,n。对于perm['a | b'、'c'、'd | e'],重复了['a'、'c']。在我的情况下,我可以生成包含所有排列的文件,并使用sort和uniq删除重复项。您介意尝试使用我的答案,看看它是否适合您的需要吗?@Sanyash是的,您的代码比创建文件然后排序更有效。为了满足我的需要,我在你的帖子中添加了一条评论。有一个答案是“我的话,但给出了重复的结果”。def perms,n=2:对于itertools.product中的p*[k.split |对于s中的k]:来自itertools.permutationsp的产量,n。对于perm['a | b'、'c'、'd | e'],重复了['a'、'c']。在我的情况下,我可以生成包含所有排列的文件,并使用sort和uniq删除重复项。您介意尝试使用我的答案,看看它是否适合您的需要吗?@Sanyash是的,您的代码比创建文件然后排序更有效。为了满足我的需要,我在你的帖子中添加了一条评论。我刚刚测试了这些真实数据,但忘了提到字符串可能超过一个字符。我在帖子中添加了一个示例案例。更新了我的答案,现在它通过了您添加的测试案例。对于任何想知道的人,请替换。加入其他:yield.jointuple\u of_strings与'A'。加入以拥有一个单独的原始entries,我也将其用于itertools.permutationslist\u of_strings中的项,n:为了创建长度为n的排列,我刚刚测试了这个真实数据,忘记了提到字符串可能超过一个字符。我在帖子中添加了一个示例案例。更新了我的答案,现在它通过了你添加的测试案例。对于任何想知道的人,替换。加入其他:yield.jointuple_of_strings与'A'。加入以拥有一个单独的原始条目我也用于itertools中的条目。permutationslist_of_strings,n:创建长度n的置换。酷!生成器表达式甚至可以使它成为一行。这比另一个正确答案更有效、更清晰!对于未来的读者,如果你只想要一个只使用列表中n个元素的排列,请记住对大型列表使用排列…,n;我在计算由原始字符串列表构造的列表的排列,这意味着你需要所有排列。酷!生成器表达式甚至可以使它成为一行。这比另一个正确答案更有效、更清晰!对于未来的读者,如果你只想要一个只使用列表中n个元素的排列,请记住对大型列表使用排列…,n;我是康普 计算从原始字符串列表构造的列表的排列,这意味着您需要所有排列。