[英]Mapping modified string indices to original string indices in Python
我是编程的新手,想就我遇到的问题寻求帮助。 我需要找出一种方法,在删除某些位置后将字符串的索引映射回原始字符串。 例如,说我有一个列表:
original_string = 'abcdefgh'
我删除了一些要点:
new_string = acfh
我需要一种方法来获取new_string
的“真实”索引。 换句话说,我想要保持original_string
位置的索引,就像在original_string
。 因此返回:
original_indices_of_new_string = [0,2,5,7]
我的一般方法是这样的:
我在original_string
字符串中找到了要删除的职位:
removed_positions = [1,3,4,6]
然后给定new_string
的索引:
new_string_indices = [0,1,2,3]
然后,我认为我应该能够执行以下操作:
original_indices_of_new_string = []
for i in new_string_indices:
offset = 0
corrected_value = i + offset
if corrected_value in removed_positions:
#somehow offset to correct value
offset+=1
else:
original_indices_of_new_string.append(corrected_value)
这实际上并没有用,因为偏移量在每次循环后都重置为0,我只想在corrected_value
位于removed_positions
(即,我想为removeed_positions 3和4偏移2,而如果连续位置不是,则仅偏移1。删除)。
我需要根据已删除的头寸而不是我保留的头寸进行此操作,因为在线下,我将删除更多的头寸,并且我想拥有一个简单的功能,即可将这些头寸映射回原始头寸时间。 我也不能只搜索已删除的部分,因为真实的字符串不够独特,无法保证找到正确的部分。
任何帮助将非常感激。 我一直在使用堆栈溢出已有一段时间,并且一直能找到我在上一个线程中遇到的问题,但是这次找不到任何东西,所以我决定自己发布一个问题! 让我知道是否需要澄清。
*字符串中的字母不是唯一的
给定您的字符串original_string = 'abcdefgh'
您可以创建索引的元组以及每个字符的字符:
>>> li=[(i, c) for i, c in enumerate(original_string)]
>>> li
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h')]
然后删除所需的字符:
>>> new_li=[t for t in li if t[1] not in 'bdeg']
>>> new_li
[(0, 'a'), (2, 'c'), (5, 'f'), (7, 'h')]
然后重新加入一个字符串:
>>> ''.join([t[1] for t in new_li])
acfh
您的“答案”是用于创建new_li
并引用那里的索引的方法:
>>> ', '.join(map(str, (t[0] for t in new_li)))
0, 2, 5, 7
如果按索引删除,则只需要从所有索引的列表开始,例如:[0、1、2、3、4],然后在每个索引处删除时,将其从该列表中删除。 例如,如果要删除索引1和3,则将执行以下操作:
idxlst.remove(1)
idxlst.remove(3)
idxlst # => [0, 2, 4]
[更新]:如果不按索引删除,则最简单的方法是先找到索引,然后继续上述解决方案,例如,如果从“ abc”中删除“ c”,请执行以下操作:
i = mystr.index('c')
# remove 'c'
idxlst.remove(i)
您可以创建一个新class
来处理这些问题
class String:
def __init__(self, myString):
self.myString = myString
self.myMap = {}
self.__createMapping(self.myString)
def __createMapping(self, myString):
index = 0
for character in myString:
# If the character already exists in the map, append the index to the list
if character in self.myMap:
self.myMap[character].append(index)
else:
self.myMap[character] = [index,]
index += 1
def removeCharacters(self, myList):
for character in self.myString:
if character in myList:
self.myString = self.myString.replace(character, '')
del self.myMap[character]
return self.myString
def getIndeces(self):
return self.myMap
if __name__ == '__main__':
myString = String('abcdef')
print myString.removeCharacters(['a', 'b']) # Prints cdef
print myString.getIndeces() # Prints each character and a list of the indeces these occur at
这将给出字符的映射以及出现它们的索引的列表。 如果希望返回单个列表,则可以添加更多功能。希望这可以使您了解如何开始
尝试尽可能接近您最初想要完成的工作,此代码应该可以工作:
big = 'abcdefgh'
small='acfh'
l = []
current = 0
while len(small) >0:
if big[current] == small[0]:
l.append(current)
small = small[1:]
else:
current += 1
print(l)
这个想法从正面开始起作用,因此您无需担心偏移。
当然前提是要通过从big
删除一些指标来实际获得small
。 否则,将引发IndexError
。 如果您需要代码更健壮,只需在最后捕获异常,然后返回一个空列表或其他内容即可。 否则,代码应该可以正常工作。
假设输入字符串中的字符是唯一的,这就是代码所发生的事情:
original_indices_of_new_string = []
for i in new_string_indices:
offset = 0
corrected_value = i + offset
if corrected_value in removed_positions:
#somehow offset to correct value
offset+=1
else:
original_indices_of_new_string.append(corrected_value)
每次在循环中将offset
设置为0
就像在循环外将其预设为0一样好。 如果您每次在循环中将i
都加0
,则最好使用i
。 这将您的代码归结为:
if i in removed_positions:
#somehow offset to correct value
pass
else:
original_indices_of_new_string.append(i)
这段代码给出的输出为[0, 2]
,逻辑正确(再次假设输入中的字符是唯一的),您应该做的是,在original_string
字符串的长度上运行循环。 那会给你你想要的。 像这样:
original_indices_of_new_string = []
for i in range(len(original_string)):
if i in removed_positions:
#somehow offset to correct value
pass
else:
original_indices_of_new_string.append(i)
print original_indices_of_new_string
打印:
[0, 2, 5, 7]
一个更简单的衬套可以达到以下目的:
original_indices_of_new_string = [original_string.index(i) for i in new_string for j in i]
希望这可以帮助。
这可能有助于将新字符串中的字符与它们在字典中原始字符串中的位置进行映射,并像这样恢复新字符串:
import operator
chars = {'a':0, 'c':2, 'f':6, 'h':8}
sorted_chars = sorted(chars.iteritems(), key=operator.itemgetter(1))
new_string = ''.join([char for char, pos in sorted_chars]) # 'acfh'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.