Python 如何避免为交换运算符生成相同的表达式
我想从一组变量和运算符开始构建一组所有可能的表达式。但是,我不想同时生成“a+b”和“b+a”,因为它们在数学上是相同的;而“a/b”和“b/a”则不是。 我试图区分交换列表和非交换列表中的运算符,但不知道如何为循环编写交换的Python 如何避免为交换运算符生成相同的表达式,python,Python,我想从一组变量和运算符开始构建一组所有可能的表达式。但是,我不想同时生成“a+b”和“b+a”,因为它们在数学上是相同的;而“a/b”和“b/a”则不是。 我试图区分交换列表和非交换列表中的运算符,但不知道如何为循环编写交换的,这样可以避免简并 primary_descriptors=['a', 'b'] commutative_operators=['+', '*'] non_commutative_operators=['-','/'] b=[] for x in primary_des
,这样可以避免简并
primary_descriptors=['a', 'b']
commutative_operators=['+', '*']
non_commutative_operators=['-','/']
b=[]
for x in primary_descriptors:
for y in commutative_operators:
b.append([x+y+z for z in primary_descriptors if z!=x])
d=[]
for x in primary_descriptors:
for y in non_commutative_operators:
d.append([x+y+z for z in primary_descriptors if z!=x])
flat_list_1 = [item for sublist in b for item in sublist] #from Alex Martelli's answer
flat_list_2 = [item for sublist in d for item in sublist]
print(flat_list_1)
print(flat_list_2)
这段代码的输出是
['a+b', 'a*b', 'b+a', 'b*a']
['a-b', 'a/b', 'b-a', 'b/a']
但是我只想在第一行中使用['a+b','a*b'.当为交换运算符编写循环时,对所有操作数运行外部循环,但仅对操作数列表中后面的操作数运行内部循环。像这样的事情,也许
for x_index, x in enumerate(primary_descriptors):
for y in commutative_operators:
b.append([x+y+z for z in primary_descriptors[x_index+1:] ])
新产出:
['a+b', 'a*b']
['a-b', 'a/b', 'b-a', 'b/a']
为交换运算符写入循环时,对所有操作数运行外部循环,但仅对操作数列表中后面的操作数运行内部循环。像这样的事情,也许
for x_index, x in enumerate(primary_descriptors):
for y in commutative_operators:
b.append([x+y+z for z in primary_descriptors[x_index+1:] ])
新产出:
['a+b', 'a*b']
['a-b', 'a/b', 'b-a', 'b/a']
这是一个itertools
解决方案itertools.排列
可用于以两种顺序获取所有对,而itertools.组合
可用于以一种顺序获取所有对:
>>> from itertools import permutations, combinations
>>> primary_descriptors='abc'
>>> commutative_operators='+*'
>>> non_commutative_operators='-/'
>>>
>>> [op.join(pair) for pair in combinations(primary_descriptors, 2) for op in commutative_operators]
['a+b', 'a*b', 'a+c', 'a*c', 'b+c', 'b*c']
>>> [op.join(pair) for pair in permutations(primary_descriptors, 2) for op in non_commutative_operators]
['a-b', 'a/b', 'a-c', 'a/c', 'b-a', 'b/a', 'b-c', 'b/c', 'c-a', 'c/a', 'c-b', 'c/b']
这是一个itertools
解决方案itertools.排列
可用于以两种顺序获取所有对,而itertools.组合
可用于以一种顺序获取所有对:
>>> from itertools import permutations, combinations
>>> primary_descriptors='abc'
>>> commutative_operators='+*'
>>> non_commutative_operators='-/'
>>>
>>> [op.join(pair) for pair in combinations(primary_descriptors, 2) for op in commutative_operators]
['a+b', 'a*b', 'a+c', 'a*c', 'b+c', 'b*c']
>>> [op.join(pair) for pair in permutations(primary_descriptors, 2) for op in non_commutative_operators]
['a-b', 'a/b', 'a-c', 'a/c', 'b-a', 'b/a', 'b-c', 'b/c', 'c-a', 'c/a', 'c-b', 'c/b']
一个好方法是使用不等式运算符,这将有效地防止“b”位于“A”之前:
combinations = []
primary_descriptors=['a', 'b']
commutative_operators=['+', '*']
for x in primary_descriptors:
for y in commutative_operators:
combinations += [(x, y, z) for z in primary_descriptors if x <= z]
print(combinations)
组合=[]
主要描述符=['a','b']
交换_算子=['+','*']
对于主描述符中的x:
对于交换_算子中的y:
如果x一个好的方法是使用不等式运算符,这将有效地防止“b”在“A”之前出现:
combinations = []
primary_descriptors=['a', 'b']
commutative_operators=['+', '*']
for x in primary_descriptors:
for y in commutative_operators:
combinations += [(x, y, z) for z in primary_descriptors if x <= z]
print(combinations)
组合=[]
主要描述符=['a','b']
交换_算子=['+','*']
对于主描述符中的x:
对于交换_算子中的y:
主描述符中z的组合+=[(x,y,z)如果x的答案很有趣,谢谢。我很快就会接受它。旁白:我能用迭代器使它更好吗?我在尝试,但无法理解。这取决于你所说的“更好”是什么意思。是的,您可以将每个嵌套循环折叠为一条语句……但这样更可读吗?您是否有太多的运算符需要提高速度?是的,我实际上可能有很多描述符(~100)和运算符(~10)。这就是我为什么想到迭代器的原因。有趣的答案,谢谢。我很快就会接受。旁白:我能用迭代器让它变得更好吗?我试过了,但没有弄明白。这取决于你所说的“更好”是什么意思。是的,您可以将每个嵌套循环折叠为一条语句……但这样更可读吗?您是否有太多的运算符需要提高速度?是的,我实际上可能有很多描述符(~100)和运算符(~10)这就是为什么我在考虑迭代器。我想我只需要<因为我在避免a*a,而且组合应该用+not来完成,。那么我就得到了我想要的。谢谢你的回答。我想我只需要<因为我在避免a*a,而且组合应该用+not来完成,。那么我就得到了我想要的。谢谢你的回答。