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

时间:2014-01-18 04:19:37

标签: python string

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

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',如何获得其索引。因为我使用了这个'索引'逻辑,所以我希望继续这样做。

6 个答案:

答案 0 :(得分:5)

根据str.index docs,签名看起来像这样

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)

答案 1 :(得分:2)

或许更为pythonic的方法是使用生成器,从而避免中间数组“找到”:

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的一年,所以我才刚刚开始觉得自己知识渊博。这是一个快速测试,包含各种类型的数据:

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()方法更具表现力,pythonic。穿孔差异是否重要取决于实际使用情况。

答案 2 :(得分:1)

你已经问过如何找到第二次出现,并得到了一个很好的答案,针对任何特定事件进行了推广。你会意识到你真正想要的是所有事情都会立刻发生。这是一种方法:

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

答案 3 :(得分:1)

您可以使用字符串的count方法查找字符串中user_input的出现次数。然后,对每个单词中user_input的每次出现使用str.index(sub,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

答案 4 :(得分:1)

如果您使用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)

希望这会有所帮助......

答案 5 :(得分:0)

这是另一个例子。

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)