2017-05-18 1 views
2

다음 목록을 고려 파이썬 개념적 순환리스트에서 2 개의 선형리스트를 작성하십시오 start 인덱스 및 end 인덱스 주어진 즉 circle[0]circle[7] 접속되는 원형의리스트로서 개념화

>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 
>>> list(enumerate(circle)) 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h')] 

circle하면 start != end, 시계 방향과 시계 반대 방향으로 선형 순회 순서를 나타내는 두 개의 목록을 만들고 싶습니다.

사례 1 : start < end

>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 
>>> start, end = 1, 6 
>>> clockwise = circle[start:end+1] 
>>> clockwise 
['b', 'c', 'd', 'e', 'f', 'g'] 
>>> counter_clockwise = circle[start::-1] + circle[:end-1:-1] 
>>> counter_clockwise 
['b', 'a', 'h', 'g'] 

사례 2 : start > end

>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 
>>> start, end = 6, 1 
>>> clockwise = circle[start:] + circle[:end+1] 
>>> clockwise 
['g', 'h', 'a', 'b'] 
>>> counter_clockwise = circle[start:end-1:-1] 
>>> counter_clockwise 
['g', 'f', 'e', 'd', 'c', 'b'] 

거기가 내가 가지고 올 것을

startend의 값에 따라, 여기 이 두리스트를 구성하는 파이썬 /보다 효율적/쉬운 방법?

+0

정확한 대답은 없지만 Numpy (http://www.numpy.org/)는 배열 구현에 유용한 기능을 많이 가지고 있습니다. – Xorgon

+0

@Xorgon 죄송합니다. Numpy는 사용할 수 없습니다. – veritasium42

답변

3

당신은 itertools.cycle 사용할 수 있습니다

import itertools 

circle = ['a', 'b', 'c', 'd', 'e', 'f', 
  'g', 'h'] 

def clockwise(start, end): 
    endless = itertools.cycle(circle) 
    if start > end: 
     end = start + (len(circle)-(start 
          -end)) 
    return [next(endless) for i in range 
      (end+1)][start:] 

def counter_clockwise(start, end): 
    endless = itertools.cycle(circle) 
    if end > start: 
     start = end + (len(circle)-(end 
          -start))  
    return [next(endless) for i in range 
      (start+1)][end:][::-1] 

# start < end: 
forward=clockwise(1, 6) 
b1=counter_clockwise(1, 6) 
#start > end: 
f1=clockwise(6, 1) 
backward=counter_clockwise(6, 1) 

print(forward) 
print(b1) 
print(f1) 
print(backward) 

출력을 : 어쩌면

['b', 'c', 'd', 'e', 'f', 'g'] 
['b', 'a', 'h', 'g'] 
['g', 'h', 'a', 'b'] 
['g', 'f', 'e', 'd', 'c', 'b'] 
+0

하지만 시작> 끝이 어때? – kuro

1
import itertools 

def slice_it(circle,start,end,step=1): 
    if end < start and step > 0: 
     end = len(circle)+end 
    if step < 0: 
     return list(itertools.islice(itertools.cycle(circle),end,start,-1*step))[::-1] 
    return list(itertools.islice(itertools.cycle(circle),start,end,step)) 

circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 

print slice_it(circle,6,1) 
print slice_it(circle,6,1,-1) 

?

0

람다 식을 시계 방향 및 시계 반대 방향 방법과 목록 조각 만들기에 사용할 수 있습니다!

이 방법은 시도한 것과 다소 유사하지만 더 평범한 방식으로 일반화되었습니다.

>>> clockwise(circle,1,6) 
['b', 'c', 'd', 'e', 'f', 'g'] 
>>> counter_clockwise(circle,1,6) 
['b', 'a', 'h', 'g'] 
>>> clockwise(circle,6,1) 
['g', 'h', 'a', 'b'] 
>>> counter_clockwise(circle,6,1) 
['g', 'f', 'e', 'd', 'c', 'b'] 
0

당신이 예처럼 counter_clockwise 실행 조건의 일부를 처리 할 수 ​​collections 모듈에서 deque을 사용할 수 있습니다 (당신은 그것을 수정하거나 당신이 원하는 경우를 향상시킬 수 있습니다) :

from collections import deque 

circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] 


clockwise = lambda x,start,end: x[start:end+1] if start < end else x[start:] + x[:end+1] 

def counter_clockwise(itertable, start, end): 
    if end > start: 
     a = deque(itertable[:start+1]) 
     b = deque(itertable[end:]) 
     a.rotate() 
     b.rotate() 
     # Or: 
     # return list(a.__iadd__(b)) 
     return list(a) + list(b) 

    if end < start: 
     return itertable[start:end-1:-1] 


print("start > end:") 
start, end = 6,1 
print(clockwise(circle, start, end)) 
print(counter_clockwise(circle, start, end)) 

print("start < end:") 
start, end = 1,6 
print(clockwise(circle, start, end)) 
print(counter_clockwise(circle, start, end)) 

출력 :

start > end: 
['g', 'h', 'a', 'b'] 
['g', 'f', 'e', 'd', 'c', 'b'] 
start < end: 
['b', 'c', 'd', 'e', 'f', 'g'] 
['b', 'a', 'h', 'g']