首页 > 解决方案 > 使用 OR 运算符的 Itertools 置换

问题描述

给定 a listof strings,我想返回字符串可能包含 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(list_of_strings, 2):
    print(''.join(str(word) for word in permutation))

印刷

a|bc
ca|b

但我想要

ac
bc
ca
cb

也就是说,使用“a”或“b”,但不能同时使用。

可能有多个带有“|”的字符串字符串。例如,list_of_strings = ['a|b', 'c', 'd|e']

一个字符串中可能有多个 OR。例如,list_of_strings = ['a|b|d|e', 'c']

前面的例子应该打印

ac
bc
dc
ec
ca
cb
cd
ce

字符串可能超过一个字符。例如,list_of_strings = ['race', 'car|horse']

输出应该是

racecar
racehorse
carrace
horserace

标签: pythonpython-3.xitertools

解决方案


只有几个步骤。

  1. 拆分每个原始字符串|以获取字符串列表。
  2. 计算字符串列表的排列。
  3. 计算每个排列的乘积
  4. 使用空字符串连接这些产品的每个元素。

使用itertoolsandoperator模块,它看起来像这样:

>>> 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并使用生成器表达式作为permutations.

strings  = ["".join(z)
             for y in permutations(x.split("|") for x in list_of_strings)
             for z in product(*y)]

推荐阅读