0

I am trying to find all the list slices that includes a specific item. Let's say I have a list w made of five morphemes, one of which is the stem stem for which I would like to find every possible slice that includes it. Here is the code I wrote for that:

stem = 'stm'
w = ['a', 'b', stem, 'c', 'd']
w2 = w
stem_index = w.index(stem)
stem_slice1 = w[stem_index:]
stem_slice2 = w[:stem_index + 1]
slices = []

while len(w) > 0:
    w = w[:-1] # chops the last item
    if stem in w and w not in slices:
        slices.append(w)

    w_ = w[1:] # then chops the first item
    if stem in w_ and w_ not in slices:
        slices.append(w_)

    w2 = w2[1:] # chops the first item
    if stem in w2 and w2 not in slices:
        slices.append(w2)

    w2_ = w2[:-1] # then chops the last item
    if stem in w2_ and w2_ not in slices:
        slices.append(w2_)

while len(stem_slice1) > 0:
    stem_slice1 = stem_slice1[:-1]
    if stem in stem_slice1 and stem_slice1 not in slices:
        slices.append(stem_slice1)

while len(stem_slice2) > 0:
    stem_slice2 = stem_slice2[1:]
    if stem in stem_slice2 and stem_slice2 not in slices:
        slices.append(stem_slice2)

print (slices)

When run, this code prints:

[['a', 'b', 'stm', 'c'], ['b', 'stm', 'c'], ['b', 'stm', 'c', 'd'], ['a', 'b', 'stm'], ['b', 'stm'], ['stm', 'c', 'd'], ['stm', 'c'], ['stm']]

It seems to work fine, but I am wondering if there is a more Pythonic way to do the same.

4
  • Could there be multiple instances of stem, any of which would mean you want the subslice? Commented Dec 21, 2017 at 20:48
  • I am working from the assumption that stem has already been designated as stem, so there is going to be only one stem. Commented Dec 21, 2017 at 20:50
  • make slices a set, and then get rid of all of the "not in" clauses. Commented Dec 21, 2017 at 20:57
  • Sets do not take lists. I would get the error: unhashable type: 'list'. Commented Dec 21, 2017 at 21:00

1 Answer 1

4

Just getting the Cartesian product of all valid start and end indices should do it. In other words, two for loops are sufficient.

stem = 'stm'
w = ['a', 'b', stem, 'c', 'd']
idx = w.index(stem)
slices = []
for start in range(idx+1):
    for end in range(idx+1, len(w)+1):
        slices.append(w[start:end])
print(slices)

Result:

[['a', 'b', 'stm'], ['a', 'b', 'stm', 'c'], ['a', 'b', 'stm', 'c', 'd'], ['b', 'stm'], ['b', 'stm', 'c'], ['b', 'stm', 'c', 'd'], ['stm'], ['stm', 'c'], ['stm', 'c', 'd']]
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Kevin. That certainly is more economical ;)
Alternatively, as a list comprehension: slices = [w[start:end] for start in range(idx+1) for end in range(idx+1, len(w)+1)]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.