badatprog
badatprog

Reputation: 19

Python List comprehension Remove same tuples but different order

I have the given lists:

breads = ["Weissbrot", "Vollkorn", "Dinkel", "Speckbrot"]
patties = ["Wildschwein", "Rind", "Halloumi", "Aubergine"]
souces = ["Kaese", "Knoblauch", "Curry"]
toppings = ["Kopfsalat", "Bacon", "Tomate"]

I have written the following code:

burger = [(bottom, patty, souce, topping, top)
          for bottom in breads
          for patty in patties
          for souce in souces
          for topping in toppings
          for top in breads
          if bottom != top
          if (bottom, patty) != ("Speckbrot", "Aubergine")
          and (top, patty) != ("Speckbrot", "Aubergine")
          and (patty, souce) != ("Aubergine", "Kaese")
          and (patty, topping) != ("Aubergine", "Bacon")
          and (patty, bottom) != ("Halloumi", "Speckbrot")
          and (patty, top) != ("Halloumi", "Speckbrot")
          and (patty, topping) != ("Halloumi", "Bacon")]

print(len(burger))

This will print out the different combinations of burgers, 276 at this moment. The correct amount is 138. The problem is that this includes duplicates like

('Weissbrot', 'Wildschwein', 'Kaese', 'Kopfsalat', 'Vollkorn')

('Vollkorn', 'Wildschwein', 'Kaese', 'Kopfsalat', 'Weissbrot')

You can see that bottom and top are the same in both tuples but in a different order. How can i remove these duplicates. It must be done through list comprehension.

Upvotes: 0

Views: 51

Answers (2)

chepner
chepner

Reputation: 531125

You can simplify this by using product and combinations from the itertools module. In particular, combinations lets generate all unique pairs of 2 different breads. Then use product to generate the list of bread-pair/patty/sauce/topping choices.

from itertools import product, combinations


bread_choices = combinations(breads, 2)
choices = product(bread_choices, patties, souces, toppings)

burger = [(bottom, patty, souce, topping, top)
           for (bottom, top), patty, souce, topping in choices
               if (bottom, patty) != ("Speckbrot", "Aubergine")
               and (top, patty) != ("Speckbrot", "Aubergine")
               and (patty, souce) != ("Aubergine", "Kaese")
               and (patty, topping) != ("Aubergine", "Bacon")
               and (patty, bottom) != ("Halloumi", "Speckbrot")
               and (patty, top) != ("Halloumi", "Speckbrot")
               and (patty, topping) != ("Halloumi", "Bacon")]

Upvotes: 2

Thierry Lathuille
Thierry Lathuille

Reputation: 24232

You could just check that `bottom <= top" to get unique combinations:

breads = ["Weissbrot", "Vollkorn", "Dinkel", "Speckbrot"]
patties = ["Wildschwein", "Rind", "Halloumi", "Aubergine"]
souces = ["Kaese", "Knoblauch", "Curry"]
toppings = ["Kopfsalat", "Bacon", "Tomate"]

burger = [(bottom, patty, souce, topping, top)
          for bottom in breads
          for patty in patties
          for souce in souces
          for topping in toppings
          for top in breads
          if bottom != top
          if (bottom, patty) != ("Speckbrot", "Aubergine")
          and (top, patty) != ("Speckbrot", "Aubergine")
          and (patty, souce) != ("Aubergine", "Kaese")
          and (patty, topping) != ("Aubergine", "Bacon")
          and (patty, bottom) != ("Halloumi", "Speckbrot")
          and (patty, top) != ("Halloumi", "Speckbrot")
          and (patty, topping) != ("Halloumi", "Bacon")
          and bottom <= top]

print(len(burger))
# 138

Upvotes: 1

Related Questions