-1

Hello everyone this is actually my first question here so please tell me if I missing some information.

I have a list which contains numbers. I want to have all possible combinations and how often these combinations occur in my list. The combinations should follow the same rules as the itertools combinations library does it.

My first try was a loop, which saves the combinations in a dictionary, but I only accomplished that to a length of 2 numbers. After that my only idea was to loop again and again, but I guess this would take forever since my list will have more then 600 elements in it.

My first try looks like that:

def clean_dic(dic, sigma): #delete all canidates were frequency is smaller then sigma
    dic = dict((k, v) for k, v in dic.items() if v >= sigma)
    
    return dic

def create_canidate(seq,d_seq): #canidate creation with CDIST
    
  
    
    for element in range(0,len(seq)):
        s_check = set()
        for skip in range (1,len(seq)-element):
            
        
        
            number = tuple([seq[element], seq[element+skip]]) 
            
            #get_freq
            if number in d_seq and number not in s_check:
                d_seq[number] += 1
            elif number not in s_check and seq[element] in d_seq and seq[element+skip] in d_seq:
                d_seq[number] = 1
                
            
            s_check.add((seq[element], seq[element+skip]))
    
    
    
    
    
    return d_seq

sequence = [1,2,3,4,1,2,1] #example sequence
#parameter
sigma = 2

#build dic
d_seq = dict()
d_seq = dict(Counter(sequence))


d_seq = clean_dic(d_seq, sigma)
d_seq = create_canidate(sequence, d_seq)

I already know that probably the best way to create all combinations would be to just use set(combinations(sequence, loop through all length)) but I cant figure out how I can then get the count without looping through everything anyway and not saving anything.....

So the question is: What would be the best way to achieve the task and how would that look like?

I would really appreciate your help :)

Regards,

Paul

Edit: Example for what I want to do. For the example Sequence [1,2,3,1,2] I would like to have the result: 1:2; 2:2; 3:1; 1,3:1; 1,1:1; 2,2:1; 2,3:1; 2,1:1; 3,1:1; 1,2,3:1; 1,2,1:1; 1,2,2:1; 1,3,1:1 ..... and so on. Note that the order has to be preserved.

Paule15
  • 1
  • 1
  • 1
    An example would be good. – Manuel Apr 15 '21 at 14:23
  • 1
    Is this related? https://math.stackexchange.com/questions/1157554/how-to-calculate-combinations-with-duplicates – Aaron Apr 15 '21 at 14:28
  • 1
    You could take one of the [solutions here](https://stackoverflow.com/questions/464864/how-to-get-all-possible-combinations-of-a-list-s-elements) and just pass it to `collections.Counter` – Mark Apr 15 '21 at 14:28
  • @Aaron no in this post they only want to calculate the total number but I need more then just that. So unfortunately that does not help for my problem – Paule15 Apr 15 '21 at 15:31
  • @MarkM Collection Counter of the itertools.combination would give me the wrong number since for [1,2,1,2] Counter(itertools.combination) results in 3 times 1,2 but I would like to have 2 times so I cant actually use it like that :( I will add an example in the Question to make it clearer what I want. – Paule15 Apr 15 '21 at 15:35
  • 1
    @Paule15 that seems to be more of an issues with how you are defining `combination` that an issue with `Counter()`. – Mark Apr 15 '21 at 16:50
  • @MarkM why is that? The combinations are actually not a problem at all. To get a count of those combinations is the major problem which I'm trying to tackle. – Paule15 Apr 16 '21 at 06:59

1 Answers1

0

I guess this is the output and the code.

If the input sequence is not sorted, (1, 1, 2) is different from (1, 2, 1), which make combination odd.

Output:

1 2
2 2
3 1
1,1 1
1,2 4
1,3 2
2,2 1
2,3 2
1,1,2 2
1,1,3 1
1,2,2 2
1,2,3 4
2,2,3 1
1,1,2,2 1
1,1,2,3 2
1,2,2,3 2
from collections import Counter
from itertools import combinations

seq = [1, 2, 3, 1, 2]
seq.sort()  # so that the combination tuples are non-decreasing
counter = Counter()

for r in range(1, len(seq)):
    counter.update(combinations(seq, r))  # let counter count the occurrences

# sort the result by combination length, combination tuple, and the count
results = sorted(counter.items(), key=lambda s: (len(s[0]), s[0], s[1]))

for components, count in results:
    print(','.join(str(s) for s in components), count)
Aaron
  • 1,255
  • 1
  • 9
  • 12
  • Hey @Aaron, thanks for your answer, it looks interesting but important is that the order need to be preserved. But I will try to change it and see if I can make your approach work. – Paule15 Apr 16 '21 at 06:51