Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在给定列表中按该顺序查找0,0,1的简单方法_Python_Python 3.x_Subsequence - Fatal编程技术网

Python 在给定列表中按该顺序查找0,0,1的简单方法

Python 在给定列表中按该顺序查找0,0,1的简单方法,python,python-3.x,subsequence,Python,Python 3.x,Subsequence,我正在尝试编写一个简单的函数,以查找0,0,1是否按该顺序出现在列表中。 它应该返回True或False 列表可以包含任意数量的数字。 对于函数zeroOne示例如下: >> ZeroZeroOne( [0,0,1] ) >> True >> ZeroZeroOne( [1,0,0] ) >> False # there are 2s in between but the following does have 0,0,1 occurring

我正在尝试编写一个简单的函数,以查找0,0,1是否按该顺序出现在列表中。
它应该返回
True
False

列表可以包含任意数量的数字。
对于函数
zeroOne
示例如下:

>> ZeroZeroOne( [0,0,1] )
>> True

>> ZeroZeroOne( [1,0,0] )
>> False

# there are 2s in between but the following does have 0,0,1 occurring and in correct order 
>> ZeroZeroOne( [0,2,2,2,2,0,1] )
>> True
我有这个功能:

def ZeroZeroOne(nums):
      
    FoundIt = False

    #quick return if defo not possible
    if (nums.count(0) < 2) and (nums.count(1) == 0):
        return FoundIt

    n = len(nums)
    for x in range(n-2):
        if nums[x] == 0:
            for i,z in enumerate(nums[(x+1):]):
                if z==0 and z!=1:
                    for j,q in enumerate(nums[(i+1):]):
                        if q==1 and q!=0:
                            FoundIt=True

    return FoundIt
defZeroOne(nums):
FoundIt=False
#如果无法进行除雾,则快速返回
如果(nums.count(0)<2)和(nums.count(1)==0):
返回FoundIt
n=len(nums)
对于范围(n-2)内的x:
如果nums[x]==0:
对于枚举中的i,z(nums[(x+1):]):
如果z==0和z=1:
对于枚举中的j,q(nums[(i+1):]):
如果q==1和q=0:
FoundIt=True
返回FoundIt
为什么此列表的函数返回True
[0,1,0,2,1]

此外……
对于一个看似简单的问题,此函数似乎过于复杂

  • Python中是否有解决此问题的正确方法—规范方法或Python方法
  • 还是一个人的方法仅仅是基于观点

    • 我想这正是你想要的:)


      您可以通过单循环O(n)时间复杂度来实现这一点。因为它是针对这个特定的案例。请尝试下面的代码

      def ZeroZeroOne(nums):
          found_pattern = []
          for num in nums:
              if num == 1:
                  found_pattern.append(1)
                  if len(found_pattern) == 3:
                      return True
                  else:
                      found_pattern = []
              elif num == 0 and len(found_pattern) < 2:
                  found_pattern.append(0)
          return False
      
      
      print(ZeroZeroOne([0, 0, 1]))
      print(ZeroZeroOne([0, 1, 0, 2, 1]))
      print(ZeroZeroOne([0, 2, 0, 1]))
      print(ZeroZeroOne([0, 0, 0, 1]))
      print(ZeroZeroOne([0, 2, 2, 2, 2, 0, 1]))
      
      defZeroOne(nums):
      找到的_模式=[]
      对于num中的num:
      如果num==1:
      找到\u模式。追加(1)
      如果len(找到的模式)=3:
      返回真值
      其他:
      找到的_模式=[]
      elif num==0且len(找到的模式)<2:
      找到\u模式。追加(0)
      返回错误
      打印(ZeroOne([0,0,1]))
      打印(ZeroZeroOne([0,1,0,2,1]))
      打印(ZeroZeroOne([0,2,0,1]))
      打印(ZeroZeroOne([0,0,0,1]))
      打印(ZeroZeroOne([0,2,2,2,2,0,1]))
      

      但我认为,如果需要的话,你也可以概括这一点。如果您想要一种通用的方法,您可能需要查看grep的工作原理,并根据您的用例对其进行修改。

      您可以从中简单地修改有序子序列测试,以获得一个优雅的解决方案:

      def ZeroZeroOne(arr):
          test = iter(a for a in arr if a in (0, 1))
          return all(z in test for z in (0, 0, 1))
      
      我现在意识到你不想接受0,10,1。


      您可以使用来检查匹配项:

      def ZeroZeroOne(arr):
          e = itertools.tee((a for a in arr if a in (0, 1)), 3)
          # move second iterator forward one
          next(e[1])
          # move third iterator forward two
          next(e[2])
          next(e[2])
          return (0, 0, 1) in zip(*e)
      
      在本例中使用
      tee
      的好处在于,它有效地为您维护了最后三个元素的滚动缓冲区。你不需要做一个新的切片或循环


      为了好玩,这里有一个更通用的纯python解决方案。它接受任何适用于
      arr
      模板的iterable:

      def contains_template(arr, template):
          template = tuple(template)
          unique = set(template)
          filtered = (a for a in arr if a in unique)
          e = itertools.tee(filtered, len(template))
          for n, it in enumerate(e):
              for _ in range(n):
                  next(it)
          return template in zip(*e)
      

      虽然
      itertools.tee
      是维护滚动缓冲区的好方法,但您可以使用列表(或者更有效地使用
      collections.deque
      )实现相同的功能:


      最后,这里是一个非常简单的解决方案,没有滚动缓冲区:

      def contains_template(arr, template):
          template = list(template)
          n = len(template)
          unique = set(template)
          filtered = [a for a in arr if a in unique]
          return any(filtered[i:i + n] == template for i in range(len(filtered) - n))
      

      您还可以使用递归函数执行此操作:

      def检查(seq,liste,i=0,j=0):
      如果i>=len(seq):
      返回真值
      如果j>=len(列表):
      返回错误
      如果seq[i]==liste[j]:
      返回检查(序号、列表、i+1、j+1)
      elif liste[j]在以下内容中:
      #查找可以从中重新启动的最后一个索引
      对于范围(i-1,-1,-1)中的k:
      如果seq[k]==liste[j]:
      如果seq[:k]==seq[i-k:i]:
      ind=k
      打破
      其他:
      ind=0
      返回检查(序号、列表、索引、j+(非i))
      其他:
      返回检查(序号、列表、i、j+1)
      #seq=[0,0,1]表示零1
      打印(检查([0,0,1],[0,0,0,0,1])#正确
      打印(检查([0,0,1],[0,200,0,0,101,1])#正确
      打印(检查([0,2,2,0,1],[0,2,0,4,2,5,2,0,3,1])#正确
      打印(检查([0,2,2,0,1],[0,2,4,2,5,2,0,3,1])#错误
      

      为什么不迭代并切片3个项目以检查它们是否为0,0,1?这看起来更适合于。在任何情况下-您可以短路
      [0,1,0,2,1]
      ,这是
      真的
      还是
      假的
      ?@l3via,而不是假的-在列表中的某个范围必须是0,…0…1,但1,0,0或0,1,0fail@whytheq不符合你的功能。还有:为什么是假的?如果第一次发现这对呢?我们需要事先制作所有的配对吗?是的,你可以切分所有选项,一旦找到匹配项,就立即中断,这样代码会更长,但速度会更快。由于没有规定以这种方式解析大量数据,因此我认为最好使用外观更好的函数:)您可以执行
      返回任何([droped[I:I+3]for I in range(len(droped)-2)])
      这将确保在找到第一个循环后立即中断循环。它还将确保如果全部失败,则返回False。如果
      arr
      小于3,则首先检查。那你什么都不用做。只需返回
      False
      Oh cool!我不知道!感谢您的建议,例如,请尝试使用列表
      [20,0,13]
      。哦,好的。对那个案子不起作用。感谢您指出添加了一个临时字符,这是一个非常优雅的解决方案。我想知道如果我们用{0,1}中的
      a替换(0,1)
      ,它会更有效吗?@MushifAliNawaz。可能是为了更多的元素。对于两个整数,只需同时检查两个整数就更有效了。@MushifAliNawaz。很高兴你喜欢。“Tee有点神秘,因为它很少有用。”MushifAliNawaz。你不必提及这篇文章的作者。我将自动收到对我答案的任何评论或编辑的通知。@whytheq。让我知道更新是否适合你。你的算法看起来不错。但是检查这个案例
      打印(检查([0,0,1],[0,0,0,0,1])
      是的,我修复了它,谢谢你的建议!(升级)感谢概括搜索术语的额外功能实际上现在还没有概括,因为
      print(检查([0,2,
      
      def contains_template(arr, template):
          template = list(template)
          unique = set(template)
          filtered = (a for a in arr if a in unique)
          buffer = [next(filtered) for _ in range(len(template) - 1)]
          buffer.insert(0, None)
          for e in filtered:
              buffer.pop(0)
              buffer.append(e)
              if template == buffer:
                  return True
          return False
      
      def contains_template(arr, template):
          template = list(template)
          n = len(template)
          unique = set(template)
          filtered = [a for a in arr if a in unique]
          return any(filtered[i:i + n] == template for i in range(len(filtered) - n))
      
      def ZeroZeroOne(nums):
          filtered_nums = [x for x in nums if x in [0,1]]
          return '*'.join([str(x) for x in [0,0,1]) in '*'.join([str(x) for x in filtered_nums])