pythonlistconditional-statementsneighbours

How to combine Python list elements on either side of i when i mets a certain condition


There is a similar question already on Stack Overflow see link, but I am having problems referencing the item before i. I'm working with a list of strings, and only need to combine neighboring strings in the list when a certain string starts with specific characters because that string is erroneously dividing the neighboring strings. For example:

list = ["a","b","<s16","c","d"]

In this case I would want to combine any two elements neighboring the string that starts with "<s16" (starts with because each occurance includes a different number). So the correct list would look like this: list = ["a","bc","d"]

I have tried several methods and the recurring problems are:

  1. i.startswith does not work with integer objects (when I try to use range(len(list)) for example for the string index)
  2. trying to reference the object before i (such as with list.pop(i-1)) results in type error for an unsupported operand type, I guess because it thinks I'm trying to subtract 1 from a string rather than reference the element before the given element that starts with <s16>

I have tried using re.match and re.findall to resolve the first issue, but it does not seem to accruately find the right list items. if any(re.match('<s16') for i in list):

Thank you in advance for any help and I also apologize in advance for my ignorance, I'm new.


Solution

  • The best is to use the re module

    import re
    
    mylist = ["<s1", "a","b","<s16", "<s18", "c", "d", "e", "f", "<s16", "g", "h", "i", "j", "<s135"]
    
    # So you will catch strings which starts with "<s" followed by some digits
    # and after zero or more entries of any caracter.
    r = "^<s\d+.*"
    i = 0
    while i < len(mylist):
        item = mylist[i]
        
        # If you are at the start of the list just pop the first item
        if (i == 0) and re.search(r, item):
            mylist.pop(i)
        
        # If you are at the end of the list just pop the last item
        elif (i == len(mylist) - 1) and re.search(r, item):
            mylist.pop(i)
        
        # If you have found a wrong item inside the list
        # continue until you delete all consecutive entries
        elif re.search(r, item):
            mylist.pop(i)
            item = mylist[i]
            while re.search(r, item):
                mylist.pop(i)
                item = mylist[i]
            
            mylist[i-1] += mylist[i]
            mylist.pop(i)
        
        else:
            i += 1
    
    print(mylist)
    
    # ['a', 'bc', 'd', 'e', 'fg', 'h', 'i', 'j']
    

    PS: You can add more options using more regex expressions for catching different cases