0

I have a string list which looks like this:

Loops = ['Loop 0 from point number 0 to 965', 
         'Loop 1 from point number 966 to 1969',
         'Loop 2 from point number 1970 to 2961']

I am trying to get the range of the point numbers from the above list of strings.

For example: LoopStart1 = 0, LoopEnd1 = 965, LoopStart2 = 966, LoopEnd2 = 1969

I can imagine using for loops or string slicing to do that but how exactly / which commands should I use to specifically take the point numbers (integers) from these list of strings? Since the numbers each have different lengths.

Thanks in advance!

Abhyuday Vaish
  • 2,357
  • 5
  • 11
  • 27
kunkoala
  • 5
  • 2
  • Show us what you tried so far. – matszwecja Apr 27 '22 at 12:06
  • I already have the first values here from this code as an example: list = [] for line in loops: list.append(line.split()[5]) with this I get a list of the starting numbers. – kunkoala Apr 27 '22 at 12:16
  • If you have guarantee that the strings will always look like that, using split like you did is fine. All you need to do to get integer from them is to cast using `int()` – matszwecja Apr 27 '22 at 12:20

2 Answers2

0

You can use regex to do it. Then create a dictionary to store all values:

import re

Loops = ['Loop 0 from point number 0 to 965', 
         'Loop 1 from point number 966 to 1969',
         'Loop 2 from point number 1970 to 2961']
d = {}
for index, value in enumerate(Loops):
    m = re.findall(r'\d+ to \d+', value) 
    m = [i.split('to') for i in m]
    d[f'LoopStart{index+1}'] = int(m[0][0])
    d[f'LoopEnd{index+1}'] = int(m[0][-1])

print(d)

Output:

{'LoopStart1': 0, 'LoopEnd1': 965, 'LoopStart2': 966, 'LoopEnd2': 1969, 'LoopStart3': 1970, 'LoopEnd3': 2961}

Explanation:

This line gets the index and item of that loop. i.e. index = 0,1,2... and value = 'Loop 0 from...', 'Loop 1 from ....'

for index, value in enumerate(Loops):

This line finds all the strings which start with a number, have 'to' in between, and end with a number.

m = re.findall(r'\d+ to \d+', value) 

This line splits the m string by to.

m = [i.split('to') for i in m]

This line adds the loop item with starting value in a dictionary called d

d[f'LoopStart{index+1}'] = int(m[0][0])

This line adds the loop item with an ending value in a dictionary called d

d[f'LoopEnd{index+1}'] = int(m[0][-1])

Also, this f'{value}' of creating strings is called f-strings.

Abhyuday Vaish
  • 2,357
  • 5
  • 11
  • 27
  • Thank you for the answer! I will try this out. I know this is out of the topic of the question but if we do it that way, can we also loop through the dictionaries? edit: Appreciate it for the depth explanation about each lines too! – kunkoala Apr 27 '22 at 12:35
  • @kunkoala looping through dictionary is the same as looping through it's keys. You can also loop through (key, value) tuples using `d.items()` – matszwecja Apr 27 '22 at 12:37
  • @kunkoala Yes, we can loop through the dictionaries. See this [answer](https://stackoverflow.com/questions/3294889/iterating-over-dictionaries-using-for-loops) – Abhyuday Vaish Apr 27 '22 at 12:37
0

You can use a nested list comprehension:

pl=[f'LoopStart{ln+1} = {ls}, LoopEnd{ln+1} = {le}' 
        for ln, ls, le in [[int(w) for w in line.split() if w.isnumeric()] 
            for line in Loops]]


>>> print(', '.join(pl))
LoopStart1 = 0, LoopEnd1 = 965, LoopStart2 = 966, LoopEnd2 = 1969, LoopStart3 = 1970, LoopEnd3 = 2961

Breaking that down, this part makes sub lists of the numbers found:

>>> sl=[[int(w) for w in line.split() if w.isnumeric()] 
...                     for line in Loops]
>>> sl
[[0, 0, 965], [1, 966, 1969], [2, 1970, 2961]]

Then this part makes a list of formatted strings from the values in those sublists:

>>> pl=[f'LoopStart{ln+1} = {ls}, LoopEnd{ln+1} = {le}' for ln, ls, le in sl]
>>> pl
['LoopStart1 = 0, LoopEnd1 = 965', 'LoopStart2 = 966, LoopEnd2 = 1969', 'LoopStart3 = 1970, LoopEnd3 = 2961']

Then join together:

>>> ', '.join(pl)
'LoopStart1 = 0, LoopEnd1 = 965, LoopStart2 = 966, LoopEnd2 = 1969, LoopStart3 = 1970, LoopEnd3 = 2961'
dawg
  • 98,345
  • 23
  • 131
  • 206