【问题标题】:How does one compare a string to the next string in a list?如何将一个字符串与列表中的下一个字符串进行比较?
【发布时间】:2011-10-05 13:01:24
【问题描述】:

我正在写一个小的 NLP 算法,我需要做以下事情:

对于列表["this", "this", "and", "that"] 中的每个字符串x,如果字符串x 和下一个字符串相同,我想打印该字符串。

【问题讨论】:

    标签: python string list compare next


    【解决方案1】:
    s = ["this", "this", "and", "that"]
    for i in xrange(1,len(s)):
        if s[i] == s[i-1]:
            print s[i]
    

    编辑:

    顺便说一句,如果您使用的是 python 3.X,请使用 range 而不是 xrange

    【讨论】:

      【解决方案2】:
      strings = ['this', 'this', 'and', 'that']
      for a, b in zip(strings, strings[1:]):
          if a == b:
              print a
      

      【讨论】:

      • 这会不必要地复制列表(嗯,除了它的第一项)。
      • 我什至不确定它是否比遍历所有元素的简单循环更具可读性/优雅性......
      • @FogleBird:完全同意 - 微优化。对于这样的事情,(阅读:非常量开销),我更愿意提前考虑。如果 OP 使用 30 项列表执行此操作,则无关紧要。但是,如果在很长的列表上执行此操作,它可能变得足够重要,可以保证使用一种几乎同样简单且易读的方法来避免这种开销。
      • 如果你需要遍历一个巨大的列表(大于 RAM),你可以使用izip() 代替zip()islice(strings, 1, None) 代替strings[1:],全部来自itertools
      【解决方案3】:

      有时,我喜欢坚持使用老式循环:

      strings = ['this', 'this', 'and', 'that']
      for i in range(0, len(strings)-1):
         if strings[i] == strings[i+1]:
            print strings[i]
      

      每个人都无需多想就知道发生了什么,而且效率很高......

      【讨论】:

        【解决方案4】:

        大多数 Pythonic 是 list comprehension,它完全是为同时循环和测试而构建的:

        >>> strings = ['this', 'this', 'and', 'that']
        
        >>> [a for (a,b) in zip(strings, strings[1:]) if a==b]
        
        ['this']
        

        或者,为了避免临时对象(h/t @9000):

        >>> import itertools as it
        >>> [a for (a,b) in it.izip(strings, it.islice(strings,1)) if a==b]
        
        ['this']
        

        【讨论】:

          【解决方案5】:

          为什么不简单呢? :

          strings = ['this', 'this', 'and', 'that', 'or', 'or', 12,15,15,15, 'end']
          
          a = strings[0]
          for x in strings:
              if x==a:
                  print x
              else:
                  a = x
          

          【讨论】:

          • 这将始终打印strings 中的第一个元素,因为 a 和 x 都以字符串 [0] 开头。
          【解决方案6】:
          TEST = ["this", "this", "and", "that"]
          for i, s in enumerate(TEST):
             if i > 0 and TEST[i-1] == s:
                print s
          
          # Prints "this"
          

          【讨论】:

            【解决方案7】:

            这是作业吗?

            l = ["this", "this", "and", "that", "foo", "bar", "bar", "baz"]
            
            for i in xrange(len(l)-1):
               try:
                  if l.index(l[i], i+1) == i+1:
                     print l[i]
               except ValueError:
                  pass
            

            【讨论】:

            • 我真的不明白你为什么使用 try/except 语句??我将简单地使用 print str(l[i]) 就可以了 :)
            • list.index() 如果未找到该项目,则会引发 ValueError 异常。这就是为什么。
            • 发生这种情况的唯一方法是删除范围和打印之间的项目? ://
            • 正如 list.index() 的文档所说:“返回列表中第一个值为 x 的项目的索引。如果没有这样的项目,则会出错。”
            【解决方案8】:

            一般来说,如果您正在处理列表中的项目并且您需要查看当前项目的邻居,您会想要使用enumerate,因为enumerate 会为您提供当前项目和它在列表中的位置。

            与使用 zip 的方法不同,此列表推导不需要重复列表:

            print [s for i, s in enumerate(test[:-1]) if s == test[i + 1]]
            

            请注意,如果test 中没有至少两个元素,则它会失败,并且test 必须是一个列表。 (zip 方法适用于任何可迭代对象。)

            【讨论】:

              【解决方案9】:

              这是一种稍微不同的方法,它使用一个特殊的类来检测序列中的重复。然后,您实际上可以使用简单的列表推导找到重复。

              class repeat_detector(object):
                  def __init__(self, initial=None):
                      self.last = initial
                  def __call__(self, current):
                      if self.last == current:
                          return True
                      self.last = current
                      return False
              
              strings = ["this", "this", "and", "that"]
              
              is_repeat = repeat_detector()
              
              repeats = [item for item in strings if is_repeat(item)]
              

              【讨论】:

                【解决方案10】:

                使用 stdlib itertools 文档中的 pairwise() 配方(我将在此处引用):

                def pairwise(iterable):
                    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
                    a, b = tee(iterable)
                    next(b, None)
                    return izip(a, b)
                

                你可以这样做:

                for a, b in pairwise(L):
                    if a == b:
                        print a
                

                或者使用生成器表达式:

                for i in (a for a, b in pairwise(L) if a==b):
                    print i
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-09-03
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-01-20
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多