Ich möchte eine Reihe aller möglichen Ausdrücke erstellen, beginnend mit einer Reihe von Variablen und Operatoren. Ich möchte jedoch nicht sowohl 'a + b' als auch 'b + a' generieren, da sie mathematisch gleich sind. während 'a / b' und 'b / a' nicht sind. Ich habe versucht, die Operatoren in kommutativen und nicht kommutativen Listen zu unterscheiden, weiß aber nicht, wie ich die kommutative for - Schleife schreiben soll, um Entartung zu vermeiden.

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)

Die Ausgabe dieses Codes ist

['a+b', 'a*b', 'b+a', 'b*a']
['a-b', 'a/b', 'b-a', 'b/a']

Aber ich möchte ['a + b', 'a * b'] nur in der ersten Zeile.

0
anotherone 17 Apr. 2018 im 21:35

3 Antworten

Beste Antwort

Wenn Sie die Schleife für kommutative Operatoren schreiben, führen Sie die äußere Schleife für alle Operanden aus, die innere Schleife jedoch nur für die später in der Operandenliste aufgeführten. So etwas vielleicht ...

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:] ])

Neue Ausgabe:

['a+b', 'a*b']
['a-b', 'a/b', 'b-a', 'b/a']
1
Prune 17 Apr. 2018 im 18:43

Ein guter Weg ist die Verwendung des Ungleichungsoperators, der effektiv verhindert, dass 'b' vor 'a' steht:

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)
2
fralau 17 Apr. 2018 im 19:14

Hier ist eine itertools Lösung. itertools.permutations kann verwendet werden, um alle Paare in beiden Reihenfolgen zu erhalten, während itertools.combinations verwendet werden kann, um alle Paare zu erhalten, jedoch nur in einer Reihenfolge:

>>> 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']
3
Paul Panzer 17 Apr. 2018 im 19:04