繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM