#python #collections #iterator
#python #Коллекции #итератор
Вопрос:
Я пытаюсь написать функцию, которая могла бы изменять элементы (типа string) в коллекции любого типа (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-адрес, и преобразует его в требуемый формат. Но я хочу, чтобы он принимал список строк, dict строк в качестве значений, (возможно) кортежи строк, dict списков строк и т.д., Чтобы изменить их значения.
Итак, что у меня есть на данный момент:
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 я мог бы использовать набор итераторов. В lua может быть только один тип коллекции. Но я не могу найти правильный способ сделать это с помощью python. Я не могу устанавливать значения с помощью итераторов, items()
метод не существует в списках и enumerate()
применим только к спискам для доступа к их элементам с индексами во время цикла. Чего мне не хватает?
Комментарии:
1. Итак, вы просто хотите повторить общую коллекцию в Python? Разве это не может быть просто сделано в цикле for:
for ad in i addr:
2. @running.t, где и как затем поместить измененные
ad
в новую версиюaddr
коллекции?
Ответ №1:
вы могли бы выполнить итерацию через 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"))
вывод:
{'0': '12', '1': '34'}
12
34
range(0, 2)
0
12
range(0, 2)
1
12
Комментарии:
1. Но могут быть и другие коллекции, кроме dict, доступ к которым осуществляется нечисловыми ключами
2. приведите пример, пожалуйста?
3. Любой пользовательский класс с похожим на dict API, но на основе списка. Например, специальная реализация хэш-таблицы со списком в качестве базового класса и dicts в качестве элементов второго уровня. Скажем, доступ, предоставляемый string, принимая код первого символа в качестве индекса списка первого уровня. Он имеет четко определенный API, похожий на dict, но с собственной дополнительной логикой. В моем случае это точно не появится, но мой вопрос концептуальный. Как избежать любой проверки типа и использовать только общий API? Не предполагая каких-либо различий в типах? Опять же, как в C : просто установите итераторы для любого, даже самого конкретного случая!
4. извините, это мой лучший ответ, единственное, что я мог видеть, это создать свой собственный модуль и импортировать его, а в вашей программе вы выполняете все тесты..