I am making product bundling using a list. Here is the list:
list_id_category = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10']
Here are the condition that I need:
- Each of bundling contain 3 products (ex: c1-c2-c3)
- Can't only have 1 type of category in a bundling (ex: c1-c1-c1 => it doesn't allowed)
- Each of bundling may have 2 same categories (ex: c1-c1-c2)
- The sequence of each bundling doesn't make a difference (ex: c1-c2-c3 = c1-c3-c2 and soon)
Here is my code:
bundling_list = []
for i in list_id_category:
catefory1 = i
for j in list_id_category:
if j != i:
category2 = j
bundle = i '-' j
for k in list_id_category:
if i != k and j != k:
category3 = k
bundle = i '-' j '-' k
bundling_list.append(bundle)
But my code just fill the 1,2,3 condition. It doesn't fill the 4th condition. Anybody know how to fix it? Thank you.
CodePudding user response:
The following generator function will work without overgenerating and filtering:
def combos(lst):
n = len(lst)
for i in range(n-1):
for j in range(i, n):
for k in range(max(i 1, j), n):
yield lst[i], lst[j], lst[k]
list(combos([1,2,3])]
# [(1, 1, 2), (1, 1, 3), (1, 2, 2), (1, 2, 3), (1, 3, 3), (2, 2, 3), (2, 3, 3)]
list(map("-".join, combos(['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10'])))
# ['c1-c1-c2', 'c1-c1-c3', 'c1-c1-c4', 'c1-c1-c5', 'c1-c1-c6',
# 'c1-c1-c7', 'c1-c1-c8', 'c1-c1-c9', 'c1-c1-c10', 'c1-c2-c2',
# 'c1-c2-c3', ... , 'c9-c10-c10']
CodePudding user response:
You can use itertools.combinations_with_replacement(iterable, r)
to build the list of all combinations with replacement, then filter to remove the combinations in which a same element is repeated 3 times:
from itertools import combinations_with_replacement
list_id_category = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'c10']
allbundlings = combinations_with_replacement(list_id_category, 3)
bundlings = [b for b in allbundlings if len(set(b)) > 1]
I prefered if len(set(b)) > 1
to if not (b[0] == b[1] and b[1] == b[2])
to generalize