【问题标题】:Python newbie clarification about tuples and stringsPython新手关于元组和字符串的说明
【发布时间】:2017-01-21 13:56:37
【问题描述】:

我刚刚了解到我可以使用以下方法检查子字符串是否在字符串中:

字符串中的子字符串

在我看来,字符串只是一种特殊的元组,其元素是字符。所以我想知道是否有一种直接的方法可以在元组中搜索元组的一部分。元组中的元素可以是任何类型。

元组中的元组切片

现在我的第二个相关问题:

>>> tu = 12 ,23, 34,56
>>> tu[:2] in tu
False

我认为我得到 False 因为 (12, 23) 不是 tu 的一个元素。但是,为什么字符串中的子字符串有效?幕后是否隐藏着语法糖?

【问题讨论】:

  • 好吧,字符串不是元组。
  • "a string is just a special kind of tuple" 这在任何直接意义上都是不正确的。字符串类不继承自元组类。
  • OK,String 不是从 Tuple 继承的。我不这么认为。在元组中搜索元组切片怎么样?怎么办?。

标签: python string tuples slice magic-function


【解决方案1】:

字符串不仅仅是一种特殊的元组。它们有许多相似的属性,特别是,它们都是迭代器,但它们是不同的类型,并且每个都以不同的方式定义 in 运算符的行为。请参阅此处的文档:https://docs.python.org/3/reference/expressions.html#in

要解决您查找一个元组是否是另一个元组的子序列的问题,编写一个类似于您的答案的算法将是可行的方法。试试这样的:

def contains(inner, outer):
  inner_len = len(inner)
  for i, _ in enumerate(outer):
    outer_substring = outer[i:i+inner_len]
    if outer_substring == inner:
      return True
  return False

【讨论】:

  • Uau!。谈论一些真正的真正的python编码!谢谢。这是一种更紧凑的代码并且更容易理解的方式。一个小问题:下划线是命名虚拟变量的常用方法还是只有你自己?。
  • 我想唯一的缺点是执行 enumerate() 的开销有点小,但为了提高代码的可维护性,我可以接受。很多时候你可以让代码更快,但如果它以牺牲可读性为代价,那可能不是一个好主意。
  • 是的,下划线是表示变量未使用的常用方式。
  • 我绝对专注于这段代码的可读性而不是速度。我想表明你可以使用更高级别的构建块来编写这样的算法。关于速度,你是对的,它不应该总是优先于可读性。此外,仅通过阅读很难判断代码的速度有多快,因此您确实需要进行基准测试。特别是,我不希望 enumerate 提供任何类型的重大开销。我的理解是,在 Python 中,即使只是访问变量也会有一些开销。因此,这比您的算法更简单这一事实也可能使其更快。
【解决方案2】:

string 不是tuple 的类型。事实上两者都属于不同的类别。如何评估in 语句将基于在相应类中定义的__contains__() 魔术函数。

阅读How do you set up the contains method in python,也许你会发现它有用。要了解 Python 中的魔法函数,请阅读:A Guide to Python's Magic Methods

【讨论】:

    【解决方案3】:

    尝试只玩元组和拼接。在这种情况下,它很容易,因为您的拼接本质上是索引。

    >>> tu = 12 ,23, 34,56  
    >>> tu
    (12, 23, 34, 56) #a tuple of ints
    >>> tu[:1] # a tuple with an int in it
    (12,) 
    >>> tu[:1] in tu #checks for a tuple against int. no match.
    False 
    >>> tu[0] in tu #checks for int against ints. matched!
    True
    >>> #you can see as we iterate through the values...
    >>> for i in tu:
             print(""+str(tu[:1])+" == " + str(i))
    
    (12,) == 12
    (12,) == 23
    (12,) == 34
    (12,) == 56
    

    拼接返回一个元组列表,但您需要进一步索引以按值而不是容器比较 in。拼接字符串返回值,字符串和in操作符可以比较值,但是拼接元组返回元组,元组是容器。

    【讨论】:

      【解决方案4】:

      这就是我完成我的第一个请求的方式,但是,它既不简单也不像pythonic。我不得不迭代 Java 方式。我无法使用“for”循环来实现它。

      def tupleInside(tupleSlice):
          i, j = 0, 0
          while j < len(tu):
              t = tu[j]
              ts = tupleSlice[i]
              print(t, ts, i, j)
              if ts == t:
                  i += 1
                  if i == len(tupleSlice):
                      return True
              else:
                  j -= i
                  i = 0
              j += 1
          return False
      
      tu = tuple('abcdefghaabedc')
      print(tupleInside(tuple(input('Tuple slice: '))))
      

      【讨论】:

        【解决方案5】:

        只需添加 Cameron Lee 的答案,使其接受包含单个整数的 inner

        def contains(inner, outer):
            try:
                inner_len = len(inner)
                for i, _ in enumerate(outer):
                    outer_substring = outer[i:i+inner_len]
                    if outer_substring == inner:
                        return True
                return False
            except TypeError:
                return inner in outer
        
        contains(4, (3,1,2,4,5))  # returns True
        contains((4), (3,1,2,4,5))  # returns True
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 2010-09-23
          相关资源
          最近更新 更多