pritesh_ugrankar
pritesh_ugrankar

Reputation: 171

Inserting a character at regular intervals in a list

I am trying to convert 10000000C9ABCDEF to 10:00:00:00:c9:ab:cd:ef

This is needed because 10000000C9ABCDEF format is how I see HBAs or host bust adapaters when I login to my storage arrays. But the SAN Switches understand 10:00:00:00:c9:ab:cd:ef notation.

I have only been able to accomplish till the following:

#script to convert WWNs to lowercase and add the :.
def wwn_convert():
    while True:
        wwn = (input('Enter the WWN or q to quit- '))
        list_wwn = list(wwn)
        list_wwn = [x.lower() for x in list_wwn]
        lower_wwn = ''.join(list_wwn)
        print(lower_wwn)
    if wwn == 'q':
        break

wwn_convert()

I tried ':'.join, but that inserts : after each character, so I get 1:0:0:0:0:0:0:0:c:9:a:b:c:d:e:f

I want the .join to go through a loop where I can say something like for i in range (0, 15, 2) so that it inserts the : after two characters, but not quite sure how to go about it. (Good that Python offers me to loop in steps of 2 or any number that I want.)

Additionally, I will be thankful if someone could direct me to pointers where I could script this better...

Please help.

I am using Python Version 3.2.2 on Windows 7 (64 Bit)

Upvotes: 10

Views: 2957

Answers (6)

Daniel Commins
Daniel Commins

Reputation: 1

Here is my simple, straightforward solution:

s = '10000000c9abcdef'

new_s = str()
for i in range(0, len(s)-1, 2):
    new_s += s[i:i+2]
    if i+2 < len(s):
        new_s += ':'

>>> new_s
'10:00:00:00:c9:ab:cd:ef'

Upvotes: 0

Dan Bolan
Dan Bolan

Reputation: 11

I think what would help you out the most is a construction in python called a slice. I believe that you can use them on any iterable object, including strings, making them quite useful and something that is generally a very good idea to know how to use.

>>> s = '10000000C9ABCDEF'
>>> [s.lower()[i:i+2] for i in range(0, len(s)-1, 2)]
['10', '00', '00', '00', 'c9', 'ab', 'cd', 'ef']
>>> ':'.join([s.lower()[i:i+2] for i in range(0, len(s)-1, 2)])
'10:00:00:00:c9:ab:cd:ef'

If you'd like to read some more about slices, they're explained very nicely in this question, as well as a part of the actual python documentation.

Upvotes: 1

ovgolovin
ovgolovin

Reputation: 13410

It may be done using grouper recipe from here.

from itertools import izip_longest

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

Using this function, the code will look like:

def join(it):
    for el in it:
        yield ''.join(el)

':'.join(join(grouper(2, s)))

It works this way:

grouper(2,s) returns tuples '1234...' -> ('1','2'), ('3','4') ...

def join(it) does this: ('1','2'), ('3','4') ... -> '12', '34' ...

':'.join(...) creates a string from iterator: '12', '34' ... -> '12:34...'

Also, it may be rewritten as:

':'.join(''.join(el) for el in grouper(2, s))

Upvotes: 0

Austin Marshall
Austin Marshall

Reputation: 3107

>>> s='10000000C9ABCDEF'
>>> si=iter(s)
>>> ':'.join(c.lower()+next(si).lower() for c in si)
>>> '10:00:00:00:c9:ab:cd:ef'

In lambda form:

>>> (lambda x: ':'.join(c.lower()+next(x).lower() for c in x))(iter(s))
'10:00:00:00:c9:ab:cd:ef'

Upvotes: 1

Facundo Casco
Facundo Casco

Reputation: 10585

>>> s = '10000000C9ABCDEF'
>>> ':'.join([s[x:x+2] for x in range(0, len(s)-1, 2)])
'10:00:00:00:C9:AB:CD:EF'

Explanation:

':'.join(...) returns a new string inserting ':' between the parts of the iterable

s[x:x+2] returns a substring of length 2 starting at x from s

range(0, len(s) - 1, 2) returns a list of integers with a step of 2

so the list comprehension would split the string s in substrings of length 2, then the join would put them back together but inserting ':' between them.

Upvotes: 2

Andrew Clark
Andrew Clark

Reputation: 208455

Here is another option:

>>> s = '10000000c9abcdef'
>>> ':'.join(a + b for a, b in zip(*[iter(s)]*2))
'10:00:00:00:c9:ab:cd:ef'

Or even more concise:

>>> import re
>>> ':'.join(re.findall('..', s))
'10:00:00:00:c9:ab:cd:ef'

Upvotes: 6

Related Questions