Get a substring for the main version from the full version

I have a script in which I have to convert full version strings only to their main parts. For example, I should convert 1.2.3.4.5.6.7 to 1.2 .

I am currently using this: '.'.join(s.split('.', 2)[:-1])

 >>> s = '1.2.3.4.5.6.7' >>> '.'.join(s.split('.', 2)[:-1]) '1.2' 

Which works great. But it is very ugly, I hope there is a better way.

Edit:

  • Performance is a problem, so answers that do not work well (although they may look nice) do not suit me.
  • '.'.join(s.split('.', 2)[:-1]) can also be '.'.join(s.split('.', 2)[:2]) just as easy
+4
source share
4 answers

Using regex is not redundant if you precompile the regular expression. Thus,

 import re pattern = re.compile(r'^[0-9]+\.[0-9]+') # ... later ... version = '1.2.3.4.5.6.7' def get_version(s): m = pattern.search(s) if m: return m.group() print get_version(version) 

It also ensures that your version matches the format.

+4
source

Using regex :

 >>> s = '1.2.3.4.5.6.7' >>> re.search(r'(\d+\.\d+)', s).group() '1.2' 

Terms of comparison:

 >>> r = re.compile(r'^(\d+\.\d+)') >>> s = '100.21.3.4.5.6.7' >>> %timeit r.search(s).group() 100000 loops, best of 3: 1.43 us per loop >>> %timeit '.'.join(s.split('.')[:2]) 1000000 loops, best of 3: 2.32 us per loop >>> %timeit '.'.join(s.split('.', 2)[:-1]) 100000 loops, best of 3: 1.28 us per loop >>> s = '100.21.3.4.5.6.7'*100 >>> %timeit r.search(s).group() 1000000 loops, best of 3: 1.96 us per loop >>> %timeit '.'.join(s.split('.')[:2]) 10000 loops, best of 3: 40.4 us per loop >>> %timeit '.'.join(s.split('.', 2)[:-1]) 100000 loops, best of 3: 2.01 us per loop >>> s = '100.21.3.4.5.6.7'*1000 >>> %timeit r.search(s).group() 1000000 loops, best of 3: 1.94 us per loop >>> %timeit '.'.join(s.split('.')[:2]) 1000 loops, best of 3: 314 us per loop >>> %timeit '.'.join(s.split('.', 2)[:-1]) 100000 loops, best of 3: 6.76 us per loop >>> s = '100.21.3.4.5.6.7'*10000 >>> %timeit r.search(s).group() 100000 loops, best of 3: 1.42 us per loop >>> %timeit '.'.join(s.split('.')[:2]) 100 loops, best of 3: 5.3 ms per loop #millisecond >>> %timeit '.'.join(s.split('.', 2)[:-1]) 10000 loops, best of 3: 104 us per loop 
Based solution

re.findall will also be slow because it requires iterating over the entire string, and re.search stops at the first match.

+2
source

Another way could be '.'.join(s.split('.')[:2]) , but it is very similar. I think there are no other effective features: you need to divide by dots, and then select only two elements.

This solution (or yours, the same) is perfect. Just avoid using regular expressions, it just overwhelms this task.

0
source

Another approach is to search for the second point and cut the line on it:

 s[:s.index('.', s.index('.')+1)] 

It should be about as fast as the split and regex versions .

0
source

Source: https://habr.com/ru/post/1497670/


All Articles