python 字符串中第二个重复字符的索引

wsxa1bj1  于 2023-01-24  发布在  Python
关注(0)|答案(9)|浏览(249)

我正在用python尝试一个hangman代码。为了匹配一个单词的一个字符,我正在使用索引函数来获取字符的位置。例如:word = 'COMPUTER'

user_input = raw_input('Enter a character :') # say 'T; is given here

if user_input in word:
                print "\nThe Character %c is present in the word \n" %user_input 
                word_dict[word.index(user_input)] = user_input

#so the output will looks like

{0: '_', 1: '_', 2: '_', 3: '_', 4: '_', 5: 'T', 6: '_', 7: '_'}

现在,我的问题来了,当它来与重复的字符。

# Another example 
>>> 'CARTOON'.index('O')
4

对于第二个“O”,如何得到它的索引。因为我已经使用了这个“索引”逻辑,我期待着继续这样做。

s5a0g9ez

s5a0g9ez1#

根据str.index文档,签名如下所示

str.index(sub[, start[, end]])

第二个参数是搜索的起始索引,所以你可以传递第一个条目的索引+1,得到下一个索引。

i = 'CARTOON'.index('O')
print 'CARTOON'.index('O', i + 1)

产出

5

上面的代码可以这样编写

data = 'CARTOON'
print data.index('O', data.index('O') + 1)

你甚至可以把它作为一个效用函数,就像这样

def get_second_index(input_string, sub_string):
    return input_string.index(sub_string, input_string.index(sub_string) + 1)

print get_second_index("CARTOON", "O")

**注意:**如果至少两次未找到字符串,则将抛出ValueError

更普遍的方式是,

def get_index(input_string, sub_string, ordinal):
    current = -1
    for i in range(ordinal):
        current = input_string.index(sub_string, current + 1)
    else:
        raise ValueError("ordinal {} - is invalid".format(ordinal))
    return current

print get_index("AAABBBCCCC", "C", 4)
aelbi1ox

aelbi1ox2#

一个可能更像Python的方法是使用生成器,从而避免中间数组'found':

def find_indices_of(char, in_string):
    index = -1
    while True:
        index = in_string.find(char, index + 1)
        if index == -1:
            break
        yield index

for i in find_indices_of('x', 'axccxx'):
    print i

1
4
5

另一种方法是枚举内置

def find_indices_of_via_enumerate(char, in_string):
    return (index for index, c in enumerate(in_string) if char == c)

这也使用了发电机。
然后我开始对python的性能差异感到好奇,我使用python已经一年了,所以我才刚刚开始真正了解python,下面是一个快速测试,使用了各种类型的数据:

test_cases = [
    ('x', ''),
    ('x', 'axxxxxxxxxxxx'),
    ('x', 'abcdefghijklmnopqrstuvw_yz'),
    ('x', 'abcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvwxyz'),
]

for test_case in test_cases:
    print "('{}', '{}')".format(*test_case)

    print "string.find:", timeit.repeat(
        "[i for i in find_indices_of('{}', '{}')]".format(*test_case),
        "from __main__ import find_indices_of",
    )
    print "enumerate  :", timeit.repeat(
        "[i for i in find_indices_of_via_enumerate('{}', '{}')]".format(*test_case),
        "from __main__ import find_indices_of_via_enumerate",
    )
    print

在我的机器上会产生以下计时结果:

('x', '')
string.find: [0.6248660087585449, 0.6235580444335938, 0.6264920234680176]
enumerate  : [0.9158611297607422, 0.9153609275817871, 0.9118690490722656]

('x', 'axxxxxxxxxxxx')
string.find: [6.01502799987793, 6.077538013458252, 5.997750997543335]
enumerate  : [3.595151901245117, 3.5859270095825195, 3.597352981567383]

('x', 'abcdefghijklmnopqrstuvw_yz')
string.find: [0.6462750434875488, 0.6512351036071777, 0.6495819091796875]
enumerate  : [2.6581480503082275, 2.6216518878936768, 2.6187551021575928]

('x', 'abcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvw_yzabcdefghijklmnopqrstuvwxyz')
string.find: [1.2539417743682861, 1.2511990070343018, 1.2702908515930176]
enumerate  : [7.837890863418579, 7.791800022125244, 7.9181809425354]

enumerate()方法更具表现力,更像Python。perf差异是否重要取决于实际用例。

uhry853o

uhry853o3#

你已经问过如何找到第二个出现的单词,并且得到了一个很好的答案,概括了任何一个具体的出现。你会意识到你真正想要的是一次找到所有出现的单词。下面是一个方法:

def find_characters(word, character):
    found = []
    last_index = -1
    while True:
        try:
            last_index = word.index(character, last_index+1)
        except ValueError:
            break
        else:
            found.append(last_index)
    return found
kxkpmulp

kxkpmulp4#

可以使用字符串的count方法来查找user_input在字符串中出现的次数,然后,对单词中每次出现user_input时使用str.index(sub,start)方法,并每次将start递增1,这样就不会每次都得到相同的索引。

if user_input in word:
    count=word.count(user_input)
    a=word.index(user_input)
    word_dict[word.index(a)]=user_input
    for i in range(count-1):
        a=word.index(user_input,a+1)
        word_dict[word.index(a)]=user_input
67up9zun

67up9zun5#

如果你使用filter,这应该是一个一行程序,因为如果你使用index,你将被强制迭代或者使用递归,在这种情况下,这两者都没有必要,你可以过滤掉与你相关的值。
使用filter很容易,下面是一行代码的示例实现:

def f1(w, c): 
    return zip(* filter(lambda (x,y): x == c, zip(w, range(len(w)))  ))[1]
f1('cartoon', 'o') # --> (4, 5)

您始终可以添加错误检查,如下所示:

def f1(w, c) :
    if c not in w: return ()
    else:          return zip(* filter(lambda (x,y): x == c, zip(w, range(len(w)))  ))[1]

如果在字符串中找不到该字符,则只会得到一个空元组。否则,将得到所有匹配的元素。如果想要通用的东西,那么依赖于字符只有一两个示例这一事实并不是正确的方法。例如:

In [18]: f1('supercalifragilisticexpialidocious', 'i')
Out[18]: (8, 13, 15, 18, 23, 26, 30)
agyaoht7

agyaoht76#

这是另一个例子。

a="samesame"
po=-1 # for this, po+1 is start from 0

for c in a:
    if c=='s':  # For example, I chose "S" what I want to find
        po = a.index(c,po+1) # if you find first element 'C' then search again in next postion
        print(po)
j1dl9f46

j1dl9f467#

抱歉,如果这个答案的格式不正确,或者我把某个地方搞砸了,因为我是新来的,这是我的第一篇文章。我在我自己的刽子手游戏中使用了下面的代码来获得一个单词中多个重复字母的索引,效果很好。希望一个新手能理解这一点。

a = "hangman"            #the chosen word
length = len(a)          #determines length of chosen word
for i in range(length)   #this will loop through the code length number of times
    if a[i] == "n":      #n is the players guess. Checks if the letter is at index i
    po = a.index("n", i) # po gets the index of the letter if previous line is true
    print(po)            #prints the position/s

希望这对某人有帮助!

niwlg2el

niwlg2el8#

def findcharpos(string, character, position=None):
    array = []
    index = -1
    while True:
        try:
            index = string.index(character, index+1)
        except ValueError:
            break
        else:
            array.append(index)
    if position == None and len(array) != 0:
        return array
    elif position > len(array):
        raise ValueError(f"The character {character} does not occur {position} 
                         times in the {string}")
    else:
        return array[position-1]
    return array
tcbh2hod

tcbh2hod9#

msg = 'samesame'
print(msg.index('s', 2)) # prints the index of second 's' in the string.

相关问题