Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python .join() iterable string

I am trying to find an easy way to add a dot . to each 3 digit as a string ('43434' -> '43.434) and I found an interesting use of join for this task:

num = '1234567'
new_num = '.'.join(num[i:i+3] for i in range(0, len(num), 3))
# new_num = 123.456.7'

Well its close to what I want. This is what I want:

(its need to be `'1.234.567'`)

Why does it work like that? When I use slicing on join, it adds the addition for each item:

num = '2333'
>>> '.'.join(num[0:2])
<<< '2.3'
>>> '.'.join(num[0:3])
<<< '2.3.3'

I read somewhere that its called string as iterable concept. Can someone help me understand it?

like image 434
Or Halimi Avatar asked May 11 '26 03:05

Or Halimi


2 Answers

Possible way,

>>> num = '1234567'
>>> '.'.join([num[i-3 if i-3 > 0 else 0:i] for i in range(len(num),-1,-3)][::-1])
'1.234.567'

A benchmark,

$ python -mtimeit -s'num="1234567"' '".".join(num[::-1][i:i+3] for i in range(0, len(num), 3))[::-1]'
100000 loops, best of 3: 4.15 usec per loop

$ python -mtimeit -s'num="1234567"' '".".join([num[i-3 if i-3 > 0 else 0:i] for i in range(len(num), -1, -3)][::-1])'
1000000 loops, best of 3: 1.87 usec per loop

Neither one stands out as clearer to me but if you prefer the first (popular solution posted) it's only slightly slower.

like image 166
Jared Avatar answered May 12 '26 16:05

Jared


Your first code sample picks up 3 digits at a time of the number and joins them. Breaking it up

>>>num = '1234567'
>>>x=[num[i:i+3] for i in range(0, len(num), 3)]
>>>x
['123', '456', '7']
>>>'.'.join(x)
'123.456.7'

The num[i:i+3] part is called slicing and explained here.

While in the second part you use the join function to connect the parts again.

>>>num = '2333'
>>>num[0:2]
23 
>>>'.'.join('23')
2.3

What you want is 1.234.567, i.e. you want to start counting three digits from the end of the string. One way would be to reverse the string, do what you are doing and reverse the result.

>>> num = '1234567'
>>> num[::-1]
'7654321'
>>> '.'.join(num[::-1][i:i+3] for i in range(0, len(num), 3))[::-1]
'1.234.567'
like image 28
RedBaron Avatar answered May 12 '26 17:05

RedBaron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!