Elegant Format for a MAC Address in Python 3.2

Question:

I am looking for a more elegant solution to formatting a MAC address with colons. I am using Python 3.2. A fancy list comprehension perhaps?

s=""
h="00233a990c21"
for i in range(0,12,2):
    s += h[i:i+2] + ":"
s=s[:-1]
print("s=",s)
Asked By: jftuga

||

Answers:

Not sure how pretty this is, but it will do what you ask:

':'.join([h[i:i+2] for i,j in enumerate(h) if not (i%2)])

gives:

'00:23:3a:99:0c:21'
Answered By: Levon

The easiest solution here is just to use str.join()

>>> ":".join(str_grouper(2, "00233a990c21"))
'00:23:3a:99:0c:21'

Here using a modified version of the grouper() recipe from the itertools docs:

def str_grouper(n, iterable):
     args = [iter(iterable)] * n
     for part in zip(*args): #itertools.izip in 2.x for efficiency.
         yield "".join(part)
Answered By: Gareth Latty

Your code is easily converted to a comprehension form:

':'.join(h[i:i+2] for i in range(0,12,2))
Answered By: Lev Levitsky

Well, I might start with something pretty specific, since you know that it is an MAC address you know the exact size and format.

print "%s:%s:%s:%s:%s:%s" % (h[0:2], h[2:4], h[4:6], h[6:8], h[8:10], h[10:12])

But we can make this better if we create a class and then tell it how to format it’s string.

class Mac():
    def __init__(self, mac):
        self.mac = mac
    def __str__(self):
        return "%s:%s:%s:%s:%s:%s" % (
            self.mac[0:2],
            self.mac[2:4],
            self.mac[4:6],
            self.mac[6:8],
            self.mac[8:10],
            self.mac[10:12])

m = Mac("123456789012")
print m
Answered By: ChipJust
>>> import itertools
>>> h = '00233a990c21'
>>> ':'.join(a+b for a, b in (itertools.izip(
...                              itertools.compress(h, itertools.cycle((1,0))),
...                              itertools.compress(h, itertools.cycle((0,1))))))
>>> '00:23:3a:99:0c:21'

Does that win for the highest density of parentheses?

Answered By: D.Shawley

This is not the shortest solution, but it accepts all common types of mac formats as inputs. It also does some validation checks.

import re

def format_mac(mac: str) -> str:
    mac = re.sub('[.:-]', '', mac).lower()  # remove delimiters and convert to lower case
    mac = ''.join(mac.split())  # remove whitespaces
    assert len(mac) == 12  # length should be now exactly 12 (eg. 008041aefd7e)
    assert mac.isalnum()  # should only contain letters and numbers
    # convert mac in canonical form (eg. 00:80:41:ae:fd:7e)
    mac = ":".join(["%s" % (mac[i:i+2]) for i in range(0, 12, 2)])
    return mac

Here is a list of mac address strings and whether they will be considered as valid or invalid:

'008041aefd7e',  # valid
'00:80:41:ae:fd:7e',  # valid
'00:80:41:AE:FD:7E',  # valid
'00:80:41:aE:Fd:7E',  # valid
'00-80-41-ae-fd-7e',  # valid
'0080.41ae.fd7e',  # valid
'00 : 80 : 41 : ae : fd : 7e',  # valid
'  00:80:41:ae:fd:7e  ',  # valid
'00:80:41:ae:fd:7ent',  # valid

'aa:00:80:41:ae:fd:7e',  # invalid
'0:80:41:ae:fd:7e',  # invalid
'ae:fd:7e',  # invalid
'$$:80:41:ae:fd:7e',  # invalid

All valid ones will be returned in the canonical form as:

'00:80:41:ae:fd:7e'
Answered By: Simon Schürg
from netaddr import EUI, mac_unix_expanded
print(EUI('00:01:02:03:04:05', dialect=mac_unix_expanded))
print(EUI('1-2-3-4-5-6', dialect=mac_unix_expanded))
Answered By: Derrick

Not new but still most elegant I think:

import re
':'.join(re.findall('..', '08002714f616'))
Answered By: TNT

late answer, but for those who, like I do, retrieve the MAC address from the uuid module, you could use this since the output you get is an integer:

from uuid import getnode

# convert the integer to an uppercase string
addr = hex(int(getnode())).split('x')[1].upper()
# format it
addr = ':'.join([addr[x:x+2].upper() for x in range(0, len(addr), 2)])

This code also works for an odd number of characters once in hex form e.g.:

Input: 6969696969
Output: 19:F6:D2:2C:9

I guess leading zeros are not handled, but let’s pretend that this won’t happen.

Answered By: D_00
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.