Изменить некоторые элементы коллекции независимо от типа коллекции - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь написать функцию, которая могла бы изменять элементы (строкового типа) в коллекции любого типа (list, dict и т. Д.) Или создавать новую коллекцию того же типа с теми же элементами, но измененными в соответствии с моими правилами .

Я довольно новичок в python и у меня есть общий вопрос, но я опишу конкретную ситуацию, чтобы быть более понятным.

Я установил чувствительный к регистру формат MAC-адресов в MongoDB, например 12:34:56:78:9a:bc. Как мы знаем, 12:34:56:78:9a:bc, 12:34:56:78:9A:BC, 12-34-56-78-9A-BC и 123456789abc - это одни и те же значения для нас и для физического представления, но они отличаются в MongoDB. Поэтому моя функция проверит, представляет ли строка MAC-адрес, и преобразует его в требуемый формат. Но я хочу, чтобы он принимал список строк, набор строк в качестве значений, (возможно) наборы строк, набор списков строк и т. Д. Для изменения их значений.

Итак, что у меня есть сейчас:

def formMacAddress(addr):
    if type(addr) is str:
        addr = addr.lower()
        if not re.match('[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$', 
                addr):
            raise ValueError("'{addr}' is not MAC address".format(addr=addr))
        return re.sub('([0-9a-f]{2})[-:]?', '\g<1>:', addr, 5)
    if type(addr) is dict:
        res = {}
        for k, v in addr.items():
            res[k] = formMacAddress(v)
        return res
    if type(addr) is list:
        res = list(addr)
        for k, v in enumerate(addr):
            res[k] = formMacAddress(v)
        return res
    raise ValueError("'{addr}' is not MAC address".format(addr=addr))

Так что проблема в том, что мне не нравятся проверки для типов коллекций с одинаковыми телами. Там может быть гораздо больше типов в будущем. Я ожидал от Python возможности избежать этого.

Например, в C ++ я мог бы использовать итераторы множеств. В Луа может быть только один тип коллекции. Но я не могу найти правильный способ сделать это с помощью Python. Я не могу устанавливать значения с помощью итераторов, метод items() не существует в списках, а enumerate() применим только к спискам для доступа к их элементам с индексами во время цикла. Чего мне не хватает?

1 Ответ

0 голосов
/ 04 апреля 2019

вы можете перебирать через dict, list или tuple: (вы должны выделить тип str)

def formMacAddress(addr):
    seq_iter = addr if isinstance(addr, dict) else range(len(addr))
    print(seq_iter)
    for i in seq_iter:
        print(addr[i])

formMacAddress({"0":"12","1":"34"})
formMacAddress(["0","12"])
formMacAddress(("1","12"))

output:

{'0': '12', '1': '34'}
12
34
range(0, 2)
0
12
range(0, 2)
1
12
...