creating selections from the elements of a list using a general number of nested loops

|▌冷眼眸甩不掉的悲伤 提交于 2021-02-08 09:54:40

问题


I am trying to create a function that takes a list as input and returns all possible selections of a particular number of elements from a list without using the inbuilt combination() function in itertools.

For example, if we pass the list [1,2,3,4] and the number 3 to such a function, the function should return [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]

I have created a version of this function if the number of elements to be selected is 3 but I do not know how to deal with a generic number of nested for loops and comparisons.

My code:

    sample_set = [1,2,3,4]
    
    def selections(input_set, number):
        if number == 3:

            #frozensets are used here so a set of sets can be generated and so that frozensets containing the same elements in different order can be removed when we apply set()
            frozenset_list = [frozenset((i, j, k)) for i in input_set for j in input_set for k in input_set if i != j !=k !=i ] 
            unique_frozenset_list = set(frozenset_list) #removing identical frozensets
            return [list(i) for i in unique_frozenset_list] #converting all frozensets to lists
    
    print(selections(sample_set, 3))

回答1:


I got a combination of indexes to remove, so if you wanted 3 items from a list of 5, there would be combinations of two indexes I could remove e.g (2,5)

I threw in some conditions to make sure there were no duplicates, and that the length of list would be to the max which would be nCr, nCr is a maths formulae.

Then I would just use these combinations to make list that didn't include the indexes from these combinations, and added to the master list final_list

import random
import math

def go(sample_set,num):
    new_list = []
    n = len(sample_set)
    r = len(sample_set) - num
    nCr = (math.factorial(n) / math.factorial(r) / math.factorial(n - r))
    while len(new_list) < int(nCr):
        co = [random.randint(0,len(sample_set)-1) for count in range(r)]
        if len(co) == len(set(co)) and co not in new_list:
            new_list.append(co)
    final_list = []
    for x in new_list:
        combination = [q for q in sample_set if sample_set.index(q) not in x]
        final_list.append(combination)
    return sorted(final_list) # sorted is optional

print(go([1, 2, 3, 4],3))

>>> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

print(go([1, 2, 3, 4, 5],3))

>>> [[1, 2, 3], [1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 4, 5], [1, 4, 5], [2, 3, 4], [2, 3, 4], [2, 3, 5], [3, 4, 5]]

I just realised I can do it forwards instead of backwards, as in just get all possible combinations of 3 indexes (or whatever number is given) and print a list based on that.

def go(sample_set,num):
    new_list = []
    n = len(sample_set)
    nCr = (math.factorial(n) / math.factorial(num) / math.factorial(n - num))
    while len(new_list) < int(nCr):
        co = [random.randint(0,len(sample_set)-1) for count in range(num)]
        if len(co) == len(set(co)) and co not in new_list:
            new_list.append(co)
    final_list = []
    for x in new_list:
        combination = [q for q in sample_set if sample_set.index(q) in x]
        final_list.append(combination)
    return sorted(final_list) # sorted is optional

print(go([1, 2, 3, 4],3))


来源:https://stackoverflow.com/questions/64881363/creating-selections-from-the-elements-of-a-list-using-a-general-number-of-nested

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!