Home > database >  python: merge list item if they are following ints but index is out of range
python: merge list item if they are following ints but index is out of range

Time:12-16

For example I have a list like this:

list = [3, 4, "-", 7, " ", 9, "/", 2]

In my context which is a calculator's typing, each digit arrive as a list item, but for example the "3", "4" should be "34". I ended up with this code:=

for index, item in enumerate(list):
    a = index   1
    if type(item) is int and type(list[a]) is int:
        list[index] = int(str(item)   str(list[a]))
        list.pop(a)

the line list.pop(a)isn't working because for the last item, you can't check if the next item is a int because the next item doesn't exist, it's out of range. Do you have any ideas about how to make this not happen?

CodePudding user response:

Yes, you can use a try/except block to handle the case where list[a] is out of range. Here's one way you could modify your code to handle this:

for index, item in enumerate(list):
    a = index   1
    try:
        if type(item) is int and type(list[a]) is int:
            list[index] = int(str(item)   str(list[a]))
            list.pop(a)
    except IndexError:
        # Handle the case where a is out of range
        pass

In the except block, you can handle the case where a is out of range in any way you see fit. For example, you could simply break out of the loop, or you could do something else entirely.

Another way to approach this problem would be to iterate over the list in reverse, so that you always have a valid index to check against. This would avoid the need for a try/except block, and it would also avoid the need to modify the list as you iterate over it, which can be error-prone. Here's an example of how you could use this approach:

for index in range(len(list)-1, 0, -1):
    if type(list[index]) is int and type(list[index-1]) is int:
        list[index-1] = int(str(list[index-1])   str(list[index]))
        list.pop(index)

In this code, we iterate over the list in reverse, starting at the second-to-last item and ending at the first item. This allows us to always check against a valid index, and it also means that we don't have to modify the list as we iterate over it, which can make the code easier to understand.

CodePudding user response:

Here are two alternative approaches:

def digits_to_num(digits):
    return sum(n*10**i for i, n in enumerate(reversed(digits)))
    
def _combine_ints(arr):
    digits = []
    for item in arr:
        if isinstance(item, int):
            digits.append(item)
        else:
            if digits:
                yield digits_to_num(digits)
                digits = []
            yield item
    if digits:
        yield digits_to_num(digits)

def combine_ints(arr):
    return list(_combine_ints(arr))

Or

import re

def combine_ints(arr):
    chunked = re.findall(r'\d |[ /*-]', ''.join(map(str, arr))
    return [int(i) if i.isdecimal() else i for i in chunked]

In either case

answer = combine_ints([1, 2, 3, 4, ' ', 5, 6]) # -> [1234, ' ', 56]

If you need to handle floating point numbers these will need to be tweaked.

CodePudding user response:

You can simply add another condition to your if statement:

for index, item in enumerate(list):
    a = index   1
    if a < len(list) and type(item) is int and type(list[a]) is int :
        list[index] = int(str(item)   str(list[a]))
        list.pop(a)
  • Related