【问题标题】:Python string index and character comparingPython字符串索引和字符比较
【发布时间】:2015-03-18 01:37:18
【问题描述】:

所以我正在尝试做这样的事情

#include <stdio.h>

int main(void)
{
    char string[] = "bobgetbob";
    int i = 0, count = 0;
    for(i; i < 10; ++i)
    {
            if(string[i] == 'b' && string[i+1] == 'o' && string[i+2] == 'b')
                    count++;
    }
    printf("Number of 'bobs' is: %d\n",count);

}

但在 python 术语中是这样工作的

count = 0
s = "bobgetbob"
for i in range(0,len(s)):
    if s[i] == 'b' and s[i+1] == 'o' and s[i+2] == 'b':
        count += 1
print "Number of 'bobs' is: %d" % count

每当我得到一个恰好以“b”结尾的字符串或倒数第二个是“b”后跟一个“o”时,我都会得到一个索引超出范围错误。现在在 c 中这不是问题,因为它仍然会与我假设的垃圾值进行比较,它适用于 c。

如何在不超出范围的情况下在 python 中执行此操作?

我可以像这样遍历字符串本身吗?

for letter in s:
    #compare stuff

如何使用上述方法比较字符串中的特定索引?如果我尝试使用

letter == 'b' and letter + 1 == 'o'

这是 python 中的无效语法,我的问题是我正在考虑 c 并且我不完全确定解决这种情况的正确语法。 我知道这样的字符串切片

for i in range(0,len(s)):
    if s[i:i+3] == "bob":
        count += 1

这解决了这个特定的问题,但是,我觉得使用特定的索引位置来比较字符是一个非常强大的工具。我一生都无法弄清楚如何在 python 中正确地做到这一点,而不会像上面的第一个 python 示例那样遇到一些破坏它的情况。

【问题讨论】:

  • 我刚刚意识到,如果我知道我正在搜索的单词的长度,我可以限制我正在搜索的字符串的范围,这样我就不会越界。例如,由于 bob 的长度为三个字母,因此在 for 循环中检查倒数第二个字母是没有意义的,因为 bob 必须至少有 3 个字母长我将范围限制为两个并且我检查的最后一个字母是倒数第三个字母.

标签: python string search slice


【解决方案1】:

我可以像这样遍历字符串本身吗?

for letter in s:
#compare stuff 

如何使用上述方法比较字符串中的特定索引?

在不具体引用索引的情况下进行此类比较的 Python 方式是:

for curr, nextt, nexttt in zip(s, s[1:], s[2:]):
    if curr == 'b' and nextt == 'o' and nexttt == 'b':
         count += 1

这避免了索引错误。您也可以使用推导式,这样就无需初始化和更新count 变量。此行将与您的 C 代码执行相同的操作:

>>> sum(1 for curr, nextt, nexttt in zip(s, s[1:], s[2:])
          if curr == 'b' and nextt == 'o' and nexttt == 'b')
2

工作原理: 这是列表之间 zip 的结果:

>>> s
'bobgetbob'
>>> s[1:]
'obgetbob'
>>> s[2:]
'bgetbob'

>>> zip(s, s[1:], s[2:])
[('b', 'o', 'b'),
 ('o', 'b', 'g'),
 ('b', 'g', 'e'),
 ('g', 'e', 't'),
 ('e', 't', 'b'),
 ('t', 'b', 'o'),
 ('b', 'o', 'b')]

在循环中,您迭代列表,将每个元组解包到三个变量。

最后,如果你真的需要索引可以使用enumerate

>>> for i, c in enumerate(s):
        print i, c   
0 b
1 o
2 b
3 g
4 e
5 t
6 b
7 o
8 b

【讨论】:

    【解决方案2】:

    一般来说,这是一种缓慢的方式;你最好尽可能多地委托给性能更高的对象方法,比如str.find

    def how_many(needle, haystack):
        """
        Given
            needle:   str to search for
            haystack: str to search in
    
        Return the number of (possibly overlapping)
          occurrences of needle which appear in haystack
    
        ex,  how_many("bb", "bbbbb")  => 4
        """
        count = 0
        i = 0      # starting search index
        while True:
            ni = haystack.find(needle, i)
            if ni != -1:
                count += 1
                i = ni + 1
            else:
                return count
    
    how_many("bob", "bobgetbob")    # => 2
    

    haystack.find(needle, i) 返回下一个出现的needle 的起始索引,从索引i 或之后开始,如果没有这样的出现,则返回-1

    所以

    "bobgetbob".find("bob", 0)    # returns 0    => found 1
    "bobgetbob".find("bob", 1)    # returns 6    => found 1
    "bobgetbob".find("bob", 7)    # returns -1   => no more
    

    【讨论】:

      【解决方案3】:

      生成器表达式和求和将是解决它的更好方法:

      print("number of bobs {}".format(sum(s[i:i+3] == "bob" for i in xrange(len(s)) )))
      

      你也可以用索引作弊,即s[i+2:i+3] 不会抛出 indexError :

      count = 0
      s = "bobgetbob"
      for i in range(0,len(s)):
          print(s[i+1:i+1])
          if s[i] == 'b' and s[i+1:i+2] == 'o' and s[i+2:i+3] == 'b':
              count += 1
      print "Number of 'bobs' is: %d" % count
      Number of 'bobs' is: 2
      

      【讨论】:

        【解决方案4】:

        试试这个 - 即转到 len(s)-2,因为在那之后你将永远不会得到一个鲍勃

        count = 0
        s = "bobgetbob"
        for i in range(len(s) - 2):
            if s[i] == 'b' and s[i + 1] == 'o' and s[i + 2] == 'b':
                count += 1
        print "Number of 'bobs' is: %d" % count
        

        【讨论】:

          【解决方案5】:
          count = 0
          for i in range(0,len(s)-2):
              if s[i] == 'b' and s[i+1] == 'o' and s[i+2] == 'b':
                  count += 1
          print "Number of 'bobs' is: %d" % count
          

          【讨论】:

            猜你喜欢
            • 2023-04-02
            • 2013-08-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-08
            • 1970-01-01
            • 1970-01-01
            • 2016-08-19
            相关资源
            最近更新 更多