Python 映射字符串结构的优雅方式
Python elegant way to map string structure
假设我事先知道字符串
"key1:key2[]:key3[]:key4"
应映射到 "newKey1[]:newKey2[]:newKey3"
然后给出 "key1:key2[2]:key3[3]:key4"
,
我的方法应该return "newKey1[2]:newKey2[3]:newKey3"
(方括号内数字顺序保持不变,如上例)
我的解决方案如下所示:
predefined_mapping = {"key1:key2[]:key3[]:key4": "newKey1[]:newKey2[]:newKey3"}
def transform(parent_key, parent_key_with_index):
indexes_in_parent_key = re.findall(r'\[(.*?)\]', parent_key_with_index)
target_list = predefined_mapping[parent_key].split(":")
t = []
i = 0
for elem in target_list:
try:
sub_result = re.subn(r'\[(.*?)\]', '[{}]'.format(indexes_in_parent_key[i]), elem)
if sub_result[1] > 0:
i += 1
new_elem = sub_result[0]
except IndexError as e:
new_elem = elem
t.append(new_elem)
print ":".join(t)
transform("key1:key2[]:key3[]:key4", "key1:key2[2]:key3[3]:key4")
打印 newKey1[2]:newKey2[3]:newKey3
作为结果。
有人可以提出一个更好、更优雅的解决方案(尤其是围绕正则表达式的使用)吗?
谢谢!
你可以更优雅地完成它,只需在 []
上拆分映射结构,然后散布 实际 数据中的索引,最后加入所有内容在一起:
import itertools
# split the map immediately on [] so that you don't have to split each time on transform
predefined_mapping = {"key1:key2[]:key3[]:key4": "newKey1[]:newKey2[]:newKey3".split("[]")}
def transform(key, source):
mapping = predefined_mapping.get(key, None)
if not mapping: # no mapping for this key found, return unaltered
return source
indexes = re.findall(r'\[.*?\]', source) # get individual indexes
return "".join(i for e in itertools.izip_longest(mapping, indexes) for i in e if i)
print(transform("key1:key2[]:key3[]:key4", "key1:key2[2]:key3[3]:key4"))
# newKey1[2]:newKey2[3]:newKey3
注意:在 Python 3 上使用 itertools.zip_longest()
。
我仍然认为您对此进行了过度设计,并且可能有一种更优雅且更不容易出错的方法来解决整个问题。我建议退后一步,着眼于更大的图景,而不是仅仅因为它似乎解决了眼前的需要就敲定了这个特定的解决方案。
假设我事先知道字符串
"key1:key2[]:key3[]:key4"
应映射到 "newKey1[]:newKey2[]:newKey3"
然后给出 "key1:key2[2]:key3[3]:key4"
,
我的方法应该return "newKey1[2]:newKey2[3]:newKey3"
(方括号内数字顺序保持不变,如上例)
我的解决方案如下所示:
predefined_mapping = {"key1:key2[]:key3[]:key4": "newKey1[]:newKey2[]:newKey3"}
def transform(parent_key, parent_key_with_index):
indexes_in_parent_key = re.findall(r'\[(.*?)\]', parent_key_with_index)
target_list = predefined_mapping[parent_key].split(":")
t = []
i = 0
for elem in target_list:
try:
sub_result = re.subn(r'\[(.*?)\]', '[{}]'.format(indexes_in_parent_key[i]), elem)
if sub_result[1] > 0:
i += 1
new_elem = sub_result[0]
except IndexError as e:
new_elem = elem
t.append(new_elem)
print ":".join(t)
transform("key1:key2[]:key3[]:key4", "key1:key2[2]:key3[3]:key4")
打印 newKey1[2]:newKey2[3]:newKey3
作为结果。
有人可以提出一个更好、更优雅的解决方案(尤其是围绕正则表达式的使用)吗?
谢谢!
你可以更优雅地完成它,只需在 []
上拆分映射结构,然后散布 实际 数据中的索引,最后加入所有内容在一起:
import itertools
# split the map immediately on [] so that you don't have to split each time on transform
predefined_mapping = {"key1:key2[]:key3[]:key4": "newKey1[]:newKey2[]:newKey3".split("[]")}
def transform(key, source):
mapping = predefined_mapping.get(key, None)
if not mapping: # no mapping for this key found, return unaltered
return source
indexes = re.findall(r'\[.*?\]', source) # get individual indexes
return "".join(i for e in itertools.izip_longest(mapping, indexes) for i in e if i)
print(transform("key1:key2[]:key3[]:key4", "key1:key2[2]:key3[3]:key4"))
# newKey1[2]:newKey2[3]:newKey3
注意:在 Python 3 上使用 itertools.zip_longest()
。
我仍然认为您对此进行了过度设计,并且可能有一种更优雅且更不容易出错的方法来解决整个问题。我建议退后一步,着眼于更大的图景,而不是仅仅因为它似乎解决了眼前的需要就敲定了这个特定的解决方案。