在Python中将修改的字符串索引映射到原始字符串索引

时间:2014-08-07 19:14:48

标签: python string mapping indices

我对编程比较陌生,想在我遇到的问题上得到一些帮助。我需要找出一种方法,在删除某些位置后将字符串的索引映射回原始字符串。例如,假设我有一个列表:

original_string = 'abcdefgh'

我删除了一些要素:

new_string = acfh

我需要一种方法来获得new_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_valueremoved_positions中,我只想发生这种情况(即我想为removed_positions偏移2) 3和4但如果没有删除连续的位置,则只有1)。

我需要根据我已经移除的位置而不是我保留的位置执行此操作,因为我将会删除更多位置并且我希望能够轻松地将这些位置映射到原来每次。我也不能只搜索我删除的部分,因为真正的字符串不够独特,无法保证找到正确的部分。

非常感谢任何帮助。我一直在使用堆栈溢出一段时间,并且总是找到我在之前的一个帖子中遇到的问题,但这次找不到一些东西所以我决定自己发一个问题!如果有任何需要澄清,请告诉我。

*字符串中的字母不是唯一的

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

如果通过索引删除,您只需要从所有索引的列表开始,例如:[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)

答案 2 :(得分:0)

您可以创建新的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

这将给出字符的映射以及它们出现的indeces列表。如果您想要返回一个列表,可以添加更多功能。希望这可以让您了解如何开始

答案 3 :(得分:0)

尽量保持尽可能接近您最初尝试完成的内容,此代码应该可以正常运行:

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)

这个想法是从前面开始的,所以你不必担心偏移。

前提条件当然是small实际上是通过从big中删除一些索引来获得的。否则,抛出IndexError。如果您需要更健壮的代码,只需在最后捕获异常并返回一个空列表或其他内容。否则代码应该可以正常工作。

答案 4 :(得分:0)

假设输入字符串中的字符是唯一的,这就是您的代码所发生的事情:

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一样好。如果您每次都在0添加i,请使用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]

希望这有帮助。

答案 5 :(得分:0)

将新字符串中的字符映射到字典中原始字符串中的位置可能会有所帮助,并恢复新字符串,如下所示:

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'