2017-01-26 1 views
2

나는 목록이 l = [1,5,8,-3,6,8,-3,2,-4,6,8]이라고 말합니다. 임을 긍정적 인 정수의 하위 목록으로 나누려고합니다. 즉 위의 목록은 나에게 [[1,5,8],[6,8],[2],[6,8]]을 줄 것입니다. 이와Python : 음수를 기반으로하는 분할 목록

l = [1,5,8,-3,6,8,-3,2,-4,6,8] 
index = 0 
def sublist(somelist): 
    a = [] 
    for i in somelist: 
     if i > 0: 
      a.append(i) 
     else: 
      global index 
      index += somelist.index(i) 
      break 
    return a 

print sublist(l) 

내가 1 하위 목록 ([1,5,8])와 3의 1 음의 정수의 인덱스 번호를 얻을 수 있습니다 : 나는 다음 시도했습니다. 이제 다시 함수를 실행하고 l[index+1:]을 전달하면 다음 하위 목록을 가져 오지 않고 index6으로 업데이트 될 것이라고 가정합니다. 그러나 그럴 수 없어, 내 인생을 위해 어떻게 함수를 루프에서 실행할지 또는 어떤 조건을 사용하여 계속 실행하여 기능을 수행 할 수 있는지 파악하지 못합니다. l[index+1:]index은 가장 최근에 발생한 부정적인 위치입니다. 정수. 어떤 도움을 주시면 감사하겠습니다.

답변

4

두 가지 수준의 목록 (여기에는 하위 목록을 포함하는 큰 목록)과 하위 목록 자체를 추적해야합니다. i이 음수가 아닌 (양수와 0을 포함하는) 큰 목록을 시작하고 하위 목록을 시작하고 현재 하위 목록에 계속 추가합니다. i이 음수이면 큰 목록에 현재 하위 목록을 추가하고 새 하위 목록을 시작하십시오. 또한 첫 번째 요소가 음수이거나 마지막 요소가 음수가 아닌 경우를 처리해야합니다.

l = [1,5,8,-3,6,8,-3,2,-4,6,8] 

def sublist(somelist): 
    result = [] 
    a = [] 
    for i in somelist: 
     if i > 0: 
      a.append(i) 
     else: 
      if a: # make sure a has something in it 
       result.append(a) 
      a = [] 
    if a: # if a is still accumulating elements 
     result.append(a) 
    return result 

결과 : 결코 변경되지

>>> sublist(l) 
[[1, 5, 8], [6, 8], [2], [6, 8]] 
+0

모르겠다 나는 두 번째'if a :'문을 완전히 이해한다. – letsc

+0

@letsc - 음수를 만났을 때'a'라는 하위 목록이'result'에 추가되므로 두 번째'a : '입력 목록의 끝에있는 양수는'a'에 추가되지만'a'는'result'에 추가되지 않습니다. – TigerhawkT3

+0

우! 환상적. 고마워요! 이미 1 번 게시되었고 이미 가지고있는 코드와 가장 가까운이 답변을 수락합니다. 다른 2 개의 답변도 작동합니다. – letsc

3

somelist 때문에, index을 다시 실행하면 항상 요소의 첫 번째 인스턴스의 인덱스를 얻을 것이다, 안 하나는 그냥했다. 인덱스와 요소를 루프 할 때 enumerate을 살펴 보는 것이 좋습니다. 따라서 인덱스를 호출 할 필요가 없습니다.

itertools.groupby를 사용하여, 당신은 한 - 라이너로이 문제를 해결하기 위해 포함 된 배터리를 사용할 수, 말했다 : 작업 여전히 가치가

from itertools import groupby 

def sublist(somelist): 
    return [list(g) for k, g in groupby(somelist, key=(0).__le__) if k] 

당신의 코드를 이해하는 것이 아니라 위의 빠른 될 것입니다 매우 간단합니다.

+0

람다 함수, 나는 그것이 더 명확하다고 생각한다. – Copperfield

+0

@Copperfield : 물론,'lambda x : x> = 0'도 옵션이지만, 나는'람다'를 원칙적으로 피한다 (나는 그들을 피할 수없는 경우로 제한한다. 그래서 하나를 사용할 때, 나는 그것이 복잡하다는 것을 안다.) 그러나 나는 특별한 부유 한 비교 방법에 직접적으로 접근하는 것은 추악하다는 것을 인정할 것이다. C 레벨 내장 함수 ('lambda's가 느리다)의 더 높은 속도를 얻고 완전한 문서화로 명명 된 함수를 사용하는 대안은 key = functools.partial (operator.le, 0)'이 될 수 있지만, 추가 수입. – ShadowRanger

0

재미 만 있으면 하나의 라이너에도 re을 사용할 수 있습니다.

l = [1,5,8,-3,6,8,-3,2,-4,6,8] 
print map(lambda x: map(int,x.split(",")), re.findall(r"(?<=[,\[])\s*\d+(?:,\s*\d+)*(?=,\s*-\d+|\])", str(l))) 

출력 : [[1, 5, 8], [6, 8], [2], [6, 8]]

1

이 코드는 다음 URL에서 확인할 개념을 사용한다 : 문제에 여기 흥미로운 개념을 적용 Python list comprehension- "pop" result from original list?

는, 다음과 같은 다른 사람들이 가지고있는 몇 가지 대안 지금까지이 질문에 게시되었습니다. 두 가지 모두 목록 작성을 사용하며 첫 번째 옵션과 두 번째 옵션의 목적을 설명하기 위해 주석 처리됩니다. 이 실험이 내 학습 곡선의 일부로 나를 위해 수행되었지만이 스레드에서 다른 사용자를 도울 수 있기를 바란다 :

좋은 점은 입력 목록이 매우 큰 경우에는 작업을 완료하기 위해 메모리 지출을 두 배로 늘릴 수 있습니다. 당신은 다른 하나를 축소시키면서 하나를 만듭니다.

이 코드는 Python 2.7 및 Python 3에서 테스트되었습니다.6 :

[1, 5, 8, 6, 9, 2, 6, 7, 999, 888]
[:

o1 = [1,5,8,-3,6,9,-4,2,-5,6,7,-7, 999, -43, -1, 888]  
           # modified version of poster's list 
o1b = [1,5,8,-3,6,8,-3,2,-4,6,8] # poster's list 

o2 = [x for x in (o1.pop() for i in range(len(o1))) \ 
if (lambda x: True if x < 0 else o1.insert(0, x))(x)] 

o2b = [x for x in (o1b.pop() for i in range(len(o1b))) \ 
if (lambda x: True if x < 0 else o1b.insert(0, x))(x)] 

print(o1) 
print(o2) 
print("") 

print(o1b) 
print(o2b) 

그것은 (iPython Jupyter 노트에) 이런 결과 집합을 생성 -1, -43, -7, -5, -4, -3]

[1,5,8,6,8,2,6,8]
[-4, -3, -3 ]

여기에는 목록 내장을 작업 말로 사용하지만 읽을 수있는 방식으로 코드를 기능화하는 또 다른 버전이 있습니다. 생각) 다른 숫자 목록으로 테스트하기 쉽습니다.

p1 = [1,5,8,-3,6,9,-4,2,-5,6,7,-7, 999, -43, -1, 888]  
           # modified version of poster's list 
p1b = [1,5,8,-3,6,8,-3,2,-4,6,8] # poster's list 

def lst_mut_byNeg_mod(x, pLst):  # list mutation by neg nums module 
    # this function only make sense in context of usage in 
    # split_pos_negs_in_list() 

    if x < 0: return True 
    else: 
     pLst.insert(0,x) 
     return False 

def split_pos_negs_in_list(pLst): 
    pLngth = len(pLst)    # reduces nesting of ((())) 
    return [x for x in (pLst.pop() for i in range(pLngth)) \ 
      if lst_mut_byNeg_mod(x, pLst)] 

p2 = split_pos_negs_in_list(p1) 
print(p1) 
print(p2) 
print("") 
p2b = split_pos_negs_in_list(p1b) 
print(p1b) 
print(p2b) 

마지막 생각 :이 짧은 때문에 일부는 아마 원래의 코드를 선호하는 것 이전에 제공 링크는 코멘트 스레드에서 아이디어의 숫자했다 :

  • 그것은에 대한 Google 검색을 권장를 " 파이썬 블룸 필터 라이브러리 "- 이것은 성능 관점에서 유망한 것으로 들리지만 아직 조사하지 못했습니다.
  • 554 개의 투표가있는 스레드에 게시물이 있지만 아직 무엇이 잘못되었을 지 설명하는 의견이 4 개 이상 있습니다 그것으로. 옵션을 탐색 할 때 가장 많은 득표를 얻는 내용을 검토하는 것이 아니라 주석 흔적을 검사하는 것이 좋습니다. 이와 같은 상황에 대해 제안 된 많은 옵션이 있습니다.
관련 문제