Sean Smith
Sean Smith

Reputation: 3

Find combinations of list in specific order Python

I have a list such as

descr_list = ["I","LOVE","DOGS"]

I want a loop that can create sub lists in the order below

["I","LOVE","DOGS"]
["I","LOVE"]
["I"]
["LOVE","DOGS"]
["LOVE"]
["DOGS"]

Here is the loop i currently have and i am getting the below output

for r in range(len(descr_list)):
    for j in range(r+1,len(descr_list)+1):
        result = descr_list[r:j]
        print(result)

['i']
['i', 'love']
['i', 'love', 'dogs']
['love']
['love', 'dogs']
['dogs']

Any help would be greatly appreciated. I know I've done this before but i just can't remember how i did it haha. I need to start at the first element(we can call x) in the list and it needs to read all elements after it. Then walk backwards by 1 element until it gets back to itself and then jump to the next element(x+1) and repeat the same process above until we reach the last element in the list.

Upvotes: 0

Views: 83

Answers (4)

 mylist = ["I","LOVE","DOGS"]

 sentences=[]
 for b in range(len(mylist)):
      for i in range(len(mylist),b,-1):
           sentence=[]
      for j in range(b,i):
            sentence.append(mylist[j])
      sentences.append(sentence)


  print(sentences)

  output:
  [['I', 'LOVE', 'DOGS'], ['I', 'LOVE'], ['I'], ['LOVE', 'DOGS'], ['LOVE'], ['DOGS']]

Upvotes: 0

Adam S
Adam S

Reputation: 1

Guessing there's a better way... but I believe this should work:

    descr_list = ["I", "LOVE", "DOGS"]
    
    for word_index, word in enumerate(descr_list):
        for i in range(len(descr_list),0,-1):
            if descr_list[word_index:i]:
                result = descr_list[word_index:i]
                print(result)

Upvotes: 0

Pablo C
Pablo C

Reputation: 4771

You can use nested loops:

l = len(descr_list)
for i in range(l):
    for j in range(l, i, -1):
        print(f"{descr_list[i:j]} slice from {i} to {j}")

['I', 'LOVE', 'DOGS'] slice from 0 to 3
['I', 'LOVE'] slice from 0 to 2
['I'] slice from 0 to 1
['LOVE', 'DOGS'] slice from 1 to 3
['LOVE'] slice from 1 to 2
['DOGS'] slice from 2 to 3

I printed i and j for a better understanding.

Upvotes: 1

Tom
Tom

Reputation: 8800

You can use itertools for getting all the combinations of the original list:

import itertools

descr_list = ["I","LOVE","DOGS"]

combos = []
for i in range(len(descr_list)):
    combos += list(itertools.combinations(descr_list, i+1))

So combos is:

[('I',),
 ('LOVE',),
 ('DOGS',),
 ('I', 'LOVE'),
 ('I', 'DOGS'),
 ('LOVE', 'DOGS'),
 ('I', 'LOVE', 'DOGS')]

To get the sort you want, look at the first word of each element of combos and find its position (i.e. index()) within descr_list. Use that as a key for the sort, but also the length of the group to prioritize longer combinations first:

>>> sorted(combos, key=lambda x: (descr_list.index(x[0]), 1/len(x)))

[('I', 'LOVE', 'DOGS'),
 ('I', 'LOVE'),
 ('I', 'DOGS'),
 ('I',),
 ('LOVE', 'DOGS'),
 ('LOVE',),
 ('DOGS',)]

Upvotes: 0

Related Questions