如何确定列表中是否包含3个连续的偶数或奇数?

4

如何确定一个列表是否包含3个连续的偶数或3个连续的奇数?

示例列表(True,False,True):

[2, 1, 3, 5]
[2, 1, 2, 5]
[2, 4, 2, 5]

最接近的代码:

evenOdd = []

while True: 
    try:
        n = int(input())
        evenOdd.append(n)
    except:
        break

for x in evenOdd:
   if x % 2 == 0:
       print("True")

2
确切的三个奇/偶数是什么? - Kent
10个回答

5

这里有一些代码。使用 zip 函数迭代连续的三元组被认为比迭代索引更符合 Python 的编程风格。如果列表少于三个项目,这将导致错误--您可以添加该错误检查。 zip 函数会在其中一个可迭代对象用尽值时停止,这正是我们想要的。

def three_evens_or_odds(alist):
    for a, b, c in zip(alist, alist[1:], alist[2:]):
        if (((a & 1) and (b & 1) and (c & 1)) or
            ((a & 1 == 0) and (b & 1 == 0) and (c & 1 == 0))):
            return True
    return False

print(three_evens_or_odds([2, 1, 3, 5]))
print(three_evens_or_odds([2, 1, 2, 5]))
print(three_evens_or_odds([2, 4, 2, 5]))

甚至更简短(借鉴了@jdehesa的想法,我应该自己想到的,所以像我一样点赞他的答案),

def three_evens_or_odds(alist):
    for a, b, c in zip(alist, alist[1:], alist[2:]):
        if a & 1 == b & 1 == c & 1:
            return True
    return False

print(three_evens_or_odds([2, 1, 3, 5]))
print(three_evens_or_odds([2, 1, 2, 5]))
print(three_evens_or_odds([2, 4, 2, 5]))

那个的打印输出结果是:
True
False
True

5
你可以使用 itertools.groupby()函数:
from itertools import groupby

def check_list(lst):
    for k, g in groupby(lst, key=lambda x: x % 2):
        if len(list(g)) == 3:
            return True
    return False    

print(check_list([2, 1, 3, 5]))  # True
print(check_list([2, 1, 2, 5]))  # False
print(check_list([2, 4, 2, 5]))  # True

这可以轻松调整以适应任何团队规模。

any(len(list(x))==3 for _, x in groupby([x%2 for x in lst])) 这样不是更简单明了吗? - Ma0

2
你可以将数字列表分块,每个块包含三个数字:
def hasThreeContiguousEvenOrOdd(numbers):
    for i in range(len(numbers) - 2):
        a, b, c = numbers[i:i + 3]
        if a % 2 == 0 and b % 2 == 0 and c % 2 == 0:
            return True
        elif a % 2 == 1 and b % 2 == 1 and c % 2 == 1:
            return True
    return False

numbers1 = [2, 1, 3, 5]
numbers2 = [2, 1, 2, 5]
numbers3 = [2, 4, 2, 5]

print(numbers1, hasThreeContiguousEvenOrOdd(numbers1))
print(numbers2, hasThreeContiguousEvenOrOdd(numbers2))
print(numbers3, hasThreeContiguousEvenOrOdd(numbers3))

输出:

[2, 1, 3, 5] True
[2, 1, 2, 5] False
[2, 4, 2, 5] True

如果你想更符合习惯或者"pythonic",你可以改进代码,例如像这样:

def hasThreeContiguousEvenOrOdd(numbers):
    for a, b, c in zip(numbers, numbers[1:], numbers[2:]):
        if a % 2 == b % 2 == c % 2:
            return True
    return False

1

一种使用两个整数计数器的方法:

Time:  O(n)
space: O(1)

函数:

def chk(alist):
    odd=even=0
    for n in alist:
        if n % 2:
            odd += 1
            even = 0
        else:
            even += 1
            odd = 0
        if odd>2 or even>2:
            return True
    return False

从您的示例输出中得到3个列表 True False True。(在Python2中测试通过)


1

另一个简短通用的解决方案:

def consecutive_evenodd(lst, n=3):
    n_uplets = ( lst[i:i+n] for i in range(len(lst)-n+1) )
    return any( sum(el % 2 for el in n_uplet) % n == 0 for n_uplet in n_uplets )

# test
inputs = [[2, 1, 3, 5],                                                
          [2, 1, 2, 5],                                                
          [2, 4, 2, 5]] 

for lst in inputs:
    print(lst, consecutive_evenodd(lst))

输出:

[2, 1, 3, 5] True
[2, 1, 2, 5] False
[2, 4, 2, 5] True

一些解释: sum(...) 部分给出了每个 n-uplet 中奇数的数量。当所有数字都是奇数或偶数时,这个总和等于 n 或零。对于其他情况,总和的结果介于两者之间。因此,只有当所有 n-uplet 数字都是奇数或偶数时,sum(...) % n 才等于 0


0
如果您正在寻找在4个元素的列表中精确查找3个奇数或偶数的方法:
def ex(l):
    return sum([1 if item%2 ==0 else -1 for item in l]) in [2, -2]


ex([2, 1, 3, 5]) # True
ex([2, 1, 2, 5]) # False
ex([2, 4, 2, 5]) # True

如果列表长度和奇偶元素的数量是参数,您可以将2和-2更改为参数。


@Ev.Kounis 这在一般情况下不应该起作用!另外2是列表长度和元素数量的参数,我只是没有将其参数化。 - ᴀʀᴍᴀɴ

0

使用 zip 创建 n 元组(在我们的情况下为 3),然后使用 all(map(lambda x: x%2, sl) 查找元组中的所有 3 个元素是否都是奇数,然后使用 any 检查是否至少有一个匹配项。

使用 anyall 可以保证需要检查的奇数或偶数的最小数量

>>> n =3
>>> three_odds_or_even = lambda lst: any(all(map(lambda x: x%2, sl)) or all(map(lambda x: not x%2, sl)) for sl in zip(*(lst[i:] for i in range(n))))
>>> three_odds_or_even([2, 1, 3, 5])
True
>>> three_odds_or_even([2, 1, 2, 5])
False
>>> three_odds_or_even([2, 4, 2, 5])
True
>>> 

0
尝试一种简单的方法来做它。维护两个标志,一个用于偶数,另一个用于奇数。如果你找到了一个偶数,增加偶数标志并重置奇数标志,反之亦然。一旦一个标志的值变成3,你就知道你已经连续找到三个了。
evenodd = []

while True:
    try:
        n = int(input())
        evenodd.append(n)
    except:
        break

evenflag = 0
oddflag = 0
print(evenodd)

for number in evenodd:
    if number % 2 == 0:
        evenflag += 1
        oddflag = 0
    else:
        oddflag += 1
        evenflag = 0
    if evenflag == 3:
        print("Found 3 consecutive even numbers")
        break
    elif oddflag == 3:
        print ("Found three consecutive odd numbers")
        break

0

这里提供了一个使用简单的 for 循环的解决方案。

思路是维护一个列表,其中的值取决于输入列表中的元素是偶数还是奇数。当您没有连续的奇数/偶数时,请清空该列表。

如果在任何时候您的追踪器列表中有 3 个项目,则函数返回 True

L1 = [2, 1, 3, 5]
L2 = [2, 1, 2, 5]
L3 = [2, 4, 2, 5]

def even_odd_consec(x, k=3):
    lst = []
    for item in x:
        is_odd = item % 2
        if not (lst and (lst[-1] == is_odd)):
            lst.clear()
        lst.append(is_odd)
        if len(lst) == k:
            return True
    return False

even_odd_consec(L1, 3)  # True
even_odd_consec(L2, 3)  # False
even_odd_consec(L3, 3)  # True

0

只需检查奇偶性是否保持最小序列长度(在此处为3)。

def determine(list_, in_a_row=3):
    prv, cntr = None, 1
    for v in list_:
        cur = bool(v % 2)

        if prv is cur:
            cntr += 1
        else:
            cntr = 1
        prv = cur

        if cntr >= in_a_row:
            return True   

    return False

dataexp = [
    ([2, 1, 3, 5],True),
    ([2, 1, 2, 5],False),
    ([2, 4, 2, 5],True),
    #hmmm, you're able to handle lists smaller than 3, right?
    ([],False),
    ]

for li, exp in dataexp:
    got = determine(li)
    msg = "exp:%s:%s:got for %s" % (exp, got, li)
    if exp == got:
        print("good! %s" % msg)
    else:
        print("bad ! %s" % msg)

输出

good! exp:True:True:got for [2, 1, 3, 5]
good! exp:False:False:got for [2, 1, 2, 5]
good! exp:True:True:got for [2, 4, 2, 5]
good! exp:False:False:got for []

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接