2017-04-04 1 views
2

저는 파이썬 초보자입니다. 그래서 저는 여기서 도움을 청할 수 있다고 생각했습니다.목록에 파이썬에서 0이 아닌 3 개의 연속적인 인덱스가 있는지 확인하십시오.

여기에 편의상 만 0과 1 두 개의 입력 목록입니다 :

x = [1, 1, 1, 0, 1] 
y = [1, 1, 0, 1, 0] 

는 세 개의 연속적인 요소가 때문에 나는 X의 경우 True를 반환 파이썬의 논리를 정의하는 것을 시도하고있다가 0이 아닌 경우; 인덱스 0 : 2는 모두 0이 아닙니다. 동일한 함수는 y가 0이 아닌 3 개의 연속 요소를 가지지 않으므로 y에 대해 아무것도 반환하지 않습니다. 나는 또한 가치에 관해서가 아니라 지표에 관해서 연속적이라는 것을 의미한다!

이 논리를 해결하는 것 외에도 함수는 원래 조건이 true 인 경우 3 개의 0이 아닌 요소로 구성된 패치의 마지막 0이 아닌 요소의 인덱스와 값을 반환해야합니다.

는 자, 내가 여기, is_three_consecutive_non_zero라는 가상 함수가 있다고 가정 해 보자는 함수가 어느 경우에 반환 것입니다 :

is_three_consecutive_non_zero(x) # should evaluates to (True, 2, 1) 

2 연속 3 사람과 1 그룹의 마지막 하나의 인덱스 0이 아닌 세 요소의 패치의 마지막 0이 아닌 요소의 값입니다.

첫 번째 출력이 false이면 함수는 다른 것을 반환하지 않습니다. 여기

은 성가신 트리오 중첩에 대한 루프 좋은 출발점이 될 수있는 조건의 경우 몇 가지와 기능 :

def is_three_consecutive_non_zero(list): 
if 0 not in list: 
    return True, len(list)-1, list[len(list)-1] 

for l in range(0, len(list)): 
    for m in range(1, len(list)): 
     for n in range(2, len(list)): 
      if (l != m) & (m != l) & (n == m + 1) & (m == l + 1): 
       if (list[l] != 0) & (list[m] != 0) & (list[n] != 0): 
        return True, n, list[n] 

하는 현실을 해보자 :

is_three_consecutive_non_zero(x) 
is_three_consecutive_non_zero(y) 

그것은 좋은 것입니다 당신이 경우 더 나은 논리를 공유 할 수 있거나 다른 사용 가능한 파이썬 모듈을 사용하는 단일 또는 2 개의 라이너 일 수 있습니다. 그건 그렇고,이 목록은 매우 작기 때문에 시간이나 공간 문제에 관심이 없습니다.

z = [0, 1, 1, 1, 1] 
is_three_consecutive_non_zero(z) # evaluates to (True, 3, 1) which is consistent with what I want 

덕분에 많은

+0

같은'list'는, 당신은 당신의 코드 –

답변

2

이 당신이 찾고있는 무엇을 : 나는 또한 세 개의 비 - 제로 요소의 첫 패치에 대한 걱정?

def f(l): 
    for i in range(len(l)-3): 
     if all(l[i:i+3]): 
      return True, i, l[i+2] 
    return False, None, None 

당신은 다시 세 개의 같은 값이 하나 라이너 당신은 그룹 다음 itertools.groupby 등을 사용하여 항목을 비 제로의 길이를 확인 할 수 any(all(l[i:i+3]) for i in range(len(l)-3))

+0

감사 패트릭에 나중에''목록()를 할 수 없을 것 같은 이름을 사용하지 마십시오 만약에 0과 1 이외의 값을 가질 수 있습니까? 이에 따라 어떻게 수정할 수 있습니까? – mansanto

+0

모든'falsy * '객체가 0 일뿐만 아니라 실패하기 때문에'all'을 사용하는 것에 대한 예약이 있습니다. –

+0

@mansanto'all'과'any' 함수는 모든 객체가 모든 객체가 진리 값을 가지고 있다고 생각한다는 사실에 의존합니다 . 시작하기 [여기] (https://docs.python.org/2.4/lib/truth.html) –

2

입니다 목록에 있는지 여부를 얻고 싶다면 여러 떼. 지수는 enumerate를 사용하여 각 그룹의 항목에 추가됩니다

from itertools import groupby 

def is_three_consecutive_non_zero(lst): 
    for k, g in groupby(enumerate(lst), lambda p: p[1]): 
     g = list(g) 
     # check that key is not 0 and group length is more than 2 
     if k != 0 and len(g) > 2: 
      return True, g[-1][0], k 


x = [1, 1, 1, 0, 1] 
y = [1, 1, 0, 1, 0] 
print is_three_consecutive_non_zero(x) 
# (True, 2, 1) 

print is_three_consecutive_non_zero(y) # should probably return a 3-item tuple 
# None 
+0

응답을 주셔서 감사합니다. is_three_consecutive_non_zero ([0, 1, 1, 1, 1])는 (True, 3, 1) 대신 (True, 4, 1)로 평가됩니다. – mansanto

1

당신은 기능이 버전을 사용할 수 있습니다. 대부분의 반복을 피할 수 있습니다. more_itertools 사용

def is_three_consecutive_non_zero(list): 
    if 0 not in list: 
     if len(list)>=3: 
      return True, len(list)-1, list[len(list)-1] 
    consecutiveNonZero=0 
    for index,num in enumerate(list): 
     if num is 0: 
      consecutiveNonZero = 0 
     else: 
      consecutiveNonZero = consecutiveNonZero+1 
     if consecutiveNonZero>=3: 
      return True, index,num 
    return False,-1,-1 
0

, 우리는 모든 인덱스를 찾아 크기 연속, 비 - 제로 값을 포함 n의 일반적인 창문에 동의합니다.

import more_itertools as mit 


def is_consecutive(seq): 
    """Return True if a sequence is consecutively increasing.""" 
    return tuple(seq) == tuple(range(seq[0], seq[-1]+1)) 

def consecutive_nonzero(lst, n=3): 
    """Return True (bool, index, value) if windows are consecutively non-zero.""" 
    grouped_idxs = [w for w in mit.windowed(mit.locate(lst), n) if is_consecutive(w)] # e.g. [(0, 1, 2)] 
    return [(True, grp[-1], lst[grp[-1]]) for grp in grouped_idxs] 

consecutive_nonzero([1, 1, 1, 0, 1])[0] 
# (True, 2, 1) 

테스트

import nose.tools as nt 


def test_consecutive(f): 
    """Verify results are consecutive and non-zero.""" 
    nt.eq_(f([1, 1, 0, 1, 0]), []) 
    nt.eq_(f([1, 1, 1, 0, 1]), [(True, 2, 1)]) 
    nt.eq_(f([1, 1, 1, 0, 1, 1, 1]), [(True, 2, 1), (True, 6, 1)]) 
    nt.eq_(f([0, 1, 2, 3, 1]), [(True, 3, 3), (True, 4, 1)]) 
    nt.eq_(f([0, 0, 1, 2, 3, 1, 1, 0], n=5), [(True, 6, 1)]) 

test_consecutive(f=consecutive_nonzero) 
관련 문제