2

I have a python list as follows:

>>>list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']

Now i want to create a create a sublist with elements from little to very. So i did the following :

>>> list1[list1.index('little'):list1.index('very')+1]
['little', 'lamb', 'which', 'was', 'very']

What I want to do is rather than specifying the entire element, check for a substring in the element using the in function and then slice the list like :

>>> list1[list1.index('lit'):list1.index('ver')+1]

how would i do that ?

0

4 Answers 4

1

As i told in my preceding answer you don't need to use list.index method, you can use the following function that is faster and also you can apply any calculation on the elements :

def drop(iterable,start,end):

    for i,x in enumerate(iterable):
        if x==start :
            for y in iterable[i:]:
                if y!=end and 'sub_string' in y: #or 'sub_string' not in y
                    yield y
                else:
                    #based on your problem do stuff
                    #yield end
                    break
Sign up to request clarification or add additional context in comments.

4 Comments

@kasra..thanks for this..and I understood your point..but I am still new to Python and trying to learn all tricks of the trade and was specifically looking for a way to do it with indexes..
@Amistad welcome but as a beginner you need to learn about pythonic ways for your problems!
i tried quite a few combinations and all other solutions break depending on the positioning of the element..this is the only one that works because of the way it is implemented..marking this as the right answer..
@Amistad Im glad about that! ;)
1

Enumerate is your friend. With that and list comprehensions it becomes pretty easy.

list1[[i for i, j in enumerate(list1) if "lit" in j][0]:[i for i, j in enumerate(list1) if "ver" in j][0]+1]

What this code does is it takes the elements only if it contains the string, but stores the index not the element. Doing this for start and end, and using the first occurrence gives the desired result.

Comments

0

To maintain readability, you will want to break it up into multiple statements rather than use a large list comprehension:

>>> list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']
>>> first = next(i for i, v in enumerate(list1) if 'lit' in v)
>>> last = next(i for i, v in enumerate(list1) if 'ver' in v)
>>> list1[first:last+1]
['little', 'lamb', 'which', 'was', 'very']

Comments

0

This is probably not an answer you are looking for (especially taking number of lines). But I want to show different approach (especially if you are new to Python):

class fuzzyFilter:
    def __init__(startSubstr, endSubstr):
        self.start = startSubstr
        self.end = endSubstr
        self.state = None

    def __call__(value):
        if self.state is None:
            if self.start in value:
                self.state = True
                return True
        elif self.state:
            if self.end in value:
                self.state = False
            return True
        return False

print filter(fuzzyFilter('lit', 'very'), list1)    

There are a couple of problems here:

  • fuzzyFilter could be used only once (or some sort of reset is required)
  • It is guaranteed, that whole list1 would be read (not always true in other answers)

Comments

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.