Insert a period after every 3 characters on a line

I have it:

from __future__ import print_function

def f_comma(p_string):
   v_string = p_string
   if (type(v_string) == type(int()) or type(v_string) == type(long()) or  
       type(v_string) == type(float())):
      v_string = str(v_string)
   else:   
      l_string = list(v_string)
      for v_index in range(3, len(l_string), 4):
         l_string.insert(v_index, ',')
      v_result = ''.join(l_string)
   return (v_result)

print (f_comma('qwertyuiopaq'))

      

I can't seem to figure out why, if I use a string longer than 11 characters, the period stops inserting, but with 11 characters, it works fine. What am I doing wrong in this part?

+3


source to share


3 answers


You can insert a comma after every nth character, for example:

>>> my_str = 'qwertyuiopaq'
>>> ','.join(my_str[i:i+3] for i in range(0, len(my_str), 3))
'qwe,rty,uio,paq'

      

This should also work for any length of strings.



Edit: Written as a function in a similar style to @mhawke's answer, with the option to change grouping / characters.

>>> def f_comma(my_str, group=3, char=','):
...     my_str = str(my_str)
...     return char.join(my_str[i:i+group] for i in range(0, len(my_str), group))
... 
>>> f_comma('qwertyuiopaq')
'qwe,rty,uio,paq'
>>> f_comma('qwertyuiopaq', group=2)
'qw,er,ty,ui,op,aq'
>>> f_comma('qwertyuiopaq', group=2, char='.')
'qw.er.ty.ui.op.aq'

      

+9


source


Here's an alternative way to do it using slicing:

def f_comma(p_string, n=3):
    return ','.join(p_string[i:i+n] for i in range(0, len(p_string), n))

      

I don't think type checking is necessary in your version. Your code checks for instances of int, long or float and then converts any of them to a string. You can just convert to string without type checking:

def f_comma(p_string, n=3):
    p_string = str(p_string)
    return ','.join(p_string[i:i+n] for i in range(0, len(p_string), n))

>>> f_comma('abcdefghijklmnop')
'abc,def,ghi,jkl,mno,p'
>>> f_comma(1234567890)
'123,456,789,0'
>>> import math
>>> f_comma(math.pi)
'3.1,415,926,535,9'

      

Now this will not handle all unicode strings:



>>> f_comma(u'abcdefg\u3030\u3031\u3032\u3033')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f_comma
UnicodeEncodeError: 'ascii' codec can't encode characters in position 7-10: ordinal not in range(128)

      

Here's where you can use isinstance()

(preferred type() ==

) to help convert non-string types:

def f_comma(p_string, n=3):
    if not isinstance(p_string, basestring):    # str or unicode
        p_string = str(p_string)                # convert only non-strings
    return ','.join(p_string[i:i+n] for i in range(0, len(p_string), n))

>>> f_comma(u'abcdefg\u3030\u3031\u3032\u3033')    # returns unicode
u'abc,def,g\u3030\u3031,\u3032\u3033'
>>> f_comma('wowwowwowwow')                        # returns str
'wow,wow,wow,wow'
>>> f_comma(math.pi)                               # returns str
'3.1,415,926,535,9'

      

Also note the use of the default argument to specify the segment length:

>>> f_comma('abcdefghijklmnop')
u'abc,def,ghi,jkl,mno,p'
>>> f_comma('abcdefghijklmnop', 6)
u'abcdef,ghijkl,mnop'

      

+2


source


This is why it doesn't work. (Rather than tackling your method, which is rather ineffective as others have shown.)

When you are .insert()

on your list, each item moves forward to make space.

The indices that you calculated earlier with using range(3, len(l_string), 4)

are no longer what you want.

0


source







All Articles