如何检查一个元素是否有连续元素python

zqdjd7g9  于 2023-03-28  发布在  Python
关注(0)|答案(3)|浏览(137)

(We知道我们想要什么元素是连续的,比如0)
说有一份名单

[1, 0, 0, 2, 5, 9, 0, 0, 0, 10]

我想计算0的连续“组”的数量(在本例中为2)在组(2,3)及其周围的两个数字([1,2],[9,10])中有多少个0(如果在最后返回一个数字加上“结束”/“开始”)。我想快速完成,而不使用许多for循环。所以最后的输出将是:

[2, [2, 1, 2], [3, 9, 10]]

最终输出的格式将是[0的组的数量,[0的长度,向右环绕,向左环绕],[其他组...]]

8xiog9wr

8xiog9wr1#

看起来你可以使用itertools.groupby并跟踪前一组零和前一组非零。当你看到一组非零时(只要你看到一些零,就会产生你的结果)。最后你可以把列表的长度放在你的结果前面:

from itertools import groupby

def zero_groups(l):
    current, prev, isZero = None, "start", None
    
    for isZero, g in groupby(l, key=lambda n: n== 0):
        c = list(g)
        if isZero:
            current = len(c)
        else:
            if current:
                yield [current, prev, c[0]]
            prev = c[-1]            
    if isZero:
        yield [current, prev, "end"]

l = [1, 0, 0, 2, 5, 9, 0, 0, 0, 10]
groups = list(zero_groups(l))  
[len(groups), *groups]
# [2, [2, 1, 2], [3, 9, 10]]

# leaving off the length for these edges cases:

list(zero_groups([0, 0, 0]))
# [[3, 'start', 'end']]

list(zero_groups([1, 2, 3]))
# []

l = [0, 0, 0, 1, 0, 0, 2, 5, 9, 0, 0, 0, 10, 0, 0, 0]
list(zero_groups(l))
# [[3, 'start', 1], [2, 1, 2], [3, 9, 10], [3, 10, 'end']]
5anewei6

5anewei62#

两种解决方案:

from itertools import groupby

def solution1(numbers):
    result = [0]
    for k, [*g] in groupby(['start', *numbers, 'end'], bool):
        if k:
            if g[0] != 'start':
                result[0] += 1
                result.append([zeros, before, g[0]])
            before = g[-1]
        else:
            zeros = len(g)
    return result

def solution2(numbers):
    prev = 'start'
    result = [0]
    for x in numbers + ['end']:
        if x:
            if not prev:
                result[-1].append(x)
        else:
            if prev:
                result[0] += 1
                result.append([1, prev])
            else:
                result[-1][0] += 1
        prev = x
    return result

tests = [
    [1, 0, 0, 2, 5, 9, 0, 0, 0, 10],
    [0, 1, 0, 0, 2, 5, 9, 0, 0, 0, 10, 0],
    [0, 0, 0],
    [1, 2, 3],
]
for numbers in tests:
    for f in solution1, solution2:
        print(f(numbers))

输出(Attempt This Online!):

[2, [2, 1, 2], [3, 9, 10]]
[2, [2, 1, 2], [3, 9, 10]]
[4, [1, 'start', 1], [2, 1, 2], [3, 9, 10], [1, 10, 'end']]
[4, [1, 'start', 1], [2, 1, 2], [3, 9, 10], [1, 10, 'end']]
[1, [3, 'start', 'end']]
[1, [3, 'start', 'end']]
[0]
[0]
kpbpu008

kpbpu0083#

这是我能想到的最好的解决方案,它是O(n)
它将在列表上循环1次,并找到所有0的组。

l = [1, 2, 3]
count = 0  # count current number of continuous 0

out = [0]

for i in range(len(l)):
    if l[i] == 0:  # if the number is 0 increase current group counter
        count += 1
    elif count == 1:  # if the number isn't 0 and the count is 1, this isn't a group
        count = 0
    elif count > 1:  # if the number isn't 0 and counter is bigger than 1, it is the end of a group
        if i - count - 1 >= 0:
            out.append([count, l[i - count - 1], l[i]])
        else:
            out.append([count, "start", l[i]])
        count = 0
if count > 1:  # there was another group of 0 but no element after the group
    if len(l) - count - 1 >= 0:
        out.append([count, l[len(l) - count - 1], "end"])  # add a list with only the element before
    else:
        out.append([count, "start", "end"])  # add a list without element before and after
out[0] = len(out) - 1  # insert number of groups

print(f"{out = }")

# --------- output ---------
# [1, 0, 0, 2, 5, 9, 0, 0, 0, 10] -> out = [2, [2, 1, 2], [3, 9, 10]]
# [0, 1, 0, 0, 2, 5, 9, 0, 0, 0, 10, 0] -> out = [2, [2, 1, 2], [3, 9, 10]]
# [0, 0, 0] -> out = [1, [3, 'start', 'end']]
# [1, 2, 3] -> out = [0]

相关问题