Python 在给定列表中按该顺序查找0,0,1的简单方法
我正在尝试编写一个简单的函数,以查找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
它应该返回
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])