Home > Net >  Make list bundling using for loop
Make list bundling using for loop

Time:11-03

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:

  1. Each of bundling contain 3 products (ex: c1-c2-c3)
  2. Can't only have 1 type of category in a bundling (ex: c1-c1-c1 => it doesn't allowed)
  3. Each of bundling may have 2 same categories (ex: c1-c1-c2)
  4. 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

  • Related