파이썬에 int 목록이 있고 출력이 시퀀스의 다른 "분화구"목록이되기를 원합니다. 분화구는 분화구의 첫 번째 정수와 같거나 분화구의 첫 번째 정수보다 큰 수에 도달 할 때까지 점차 커지는 내림차순 정수로 시작하는 일련의 숫자로 정의합니다. 마지막 숫자가 첫 번째 숫자와 같거나 작 으면 분화구 끝에있는 출력에 있어야합니다. 마지막 숫자가 분화구의 첫 번째 숫자보다 크면 출력 목록 끝에 추가하면 안됩니다.
예를 들어, 목록의 경우 : 1,2,3,4,5,6,5,4,3,4,5,6,7,8,9 "분화구"는 다음과 같습니다. 6,5,4,3 , 4,5,6
내 코드 :
def find_crater(my_list):
cur_crater = []
for i in range(len(my_list)-1):
#check if the numbers are decreasing
if (my_list[i] - my_list[i+1] > 0):
cur_crater.append(my_list[i])
#if increasing - check if we're in a crater
#and if current number is smaller than begining of crater
elif len(cur_crater) > 1 and my_list[i] <= cur_crater[0]:
cur_crater.append(my_list[i])
#print crater and empty list
elif len(cur_crater) > 1 and my_list[i+1] > cur_crater[0]:
print(cur_crater)
cur_crater = []
#continue if we're out of a crater
else:
continue
#catching the last crater in the list
if len(cur_crater) > 1:
#include last int
if my_list[i] - my_list[-1] < 0 and my_list[-1] <= cur_crater[0]:
cur_crater.append(my_list[-1])
print(cur_crater)
return
두 목록에서 함수를 호출했습니다. 첫 번째 출력은 예상대로입니다.
ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
Ok 목록 출력 [편집 :별로 괜찮지 않음-첫 번째 '4'를 생략 했으므로 결국 그렇게 옳지 않은 것으로 밝혀 짐] :
[12, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
그러나 두 번째 목록은 두 개의 크레이터 목록을 출력에서 하나의 목록으로 결합합니다.
problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 19, 25, 19, 12, 23, 25, 27]
문제가있는 출력 :
[12, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17, 27, 19, 25, 19, 12, 23, 25]
나는 기대했다 :
[12, 4, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[27, 19, 25, 19, 12, 23, 25, 27]
my_list [i + 1]> cur_crater [0]을 작성하여이 문제를 처리하려고했습니다. 따라서 목록에서 다음 int의 크기를 확인합니다.하지만 수정되지 않는 것 같습니다. [하지만 코드에 남겨 두었습니다. 누군가가 왜 그것이 잘못되었거나 작동하지 않는지 설명하기를 바라면서 트릭을 수행하지 않습니다.].
결론적으로, 사이에 정수가 하나 뿐인 분화구 바로 뒤에 분화구가 있으면 내 코드가 처리 할 수 없습니다.
입력이 다음과 같은 경우 :
[12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 10, 9, 8, 6, 9, 10]
그런 다음 출력은 하나의 긴 목록이지만 목록 항목 12 이후와 목록 항목 21 이전으로 나누고 싶지만 출력은 하나의 긴 목록입니다.
더 좋고 효율적인 솔루션에 대한 더 많은 아이디어를 제공 할 수있는 라이브러리 또는 방법에 대한 정보를 얻고 싶습니다.
예상되는 출력이 잘못된 것으로 가정하고, 원하는 것은> = 요소를 찾을 때까지> = 체인의 시작 부분으로 이동하고 단일 요소 만 포함하는 체인을 잡는 것입니다.
def craters(lst):
it = iter(lst)
# get start of first chain
first = next(it)
tmp = [first]
# iterate over the remaining
for ele in it:
# >= ends chain
if ele >= first:
# if equal, add it and call
# next(it) to set the next first element.
if ele == first:
tmp.append(ele)
yield tmp
first = next(it)
tmp = [first]
# else yield the group if it has > 1 element.
# if it has 1 element it is not a descending start sequecne
else:
if len(tmp) > 1:
yield tmp
tmp = [ele]
first = ele
else:
tmp.append(ele)
if len(tmp) > 1: # catch single element last
yield tmp
산출:
In [5]: ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
...: 17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
In [6]: problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23,
...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
...: 17, 27, 19, 25, 19, 12, 23, 25, 27]
In [7]: ex_ok = [[12, 4, 7, 4, 2, 4, 5, 6, 5, 12],
...: [26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
...: [28, 19, 17, 19, 21, 19, 12, 23, 25, 27]]
In [8]: ex_p = [[12,4, 7, 4, 2, 4, 5, 6, 5, 12],
...: [26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
...: [27, 19, 25, 19, 12, 23, 25, 27]]
In [9]: print(list(craters(problematic)) == ex_p)
True
In [10]: print(list(craters(ok_list)) == ex_ok)
True
In [11]: print(list(craters([12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 10, 9, 8, 6, 9, 10])))
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12], [21, 10, 9, 8, 6, 9, 10]]
In [12]: list(craters([1, 2, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 7, 8, 9]))
Out[13]: [[6, 5, 4, 3, 4, 5, 6]]
이는 슬라이싱 / 인덱싱을 포함하지 않으며 각 그룹을 느리게 반환 할 수 있습니다.
알고리즘을 단순화하기위한 단계는 다음과 같습니다.
첫 번째 요소로 시작한 다음 다음 요소가> =인지 확인하고, 같고 동일한 경우 그룹에 추가하고> 그룹 의 새 시작 이 되도록 설정합니다 .
새 첫 번째 요소가 다음 요소보다 크지 않으면 해당 그룹의 길이는 내림차순으로 시작하는 일련의 숫자를 충족하지 않으므로 1 이됩니다 . 그래서 우리는 계속해서 소비하고 다음 요소를 시퀀스 의 첫 번째 요소가되도록 설정합니다. 하나가 다음 요소 인 것을 찾을 때까지, 이것이 호출 next(it)
이하는 일입니다. 그리고 나서 우리는 그냥 씻고 반복하면됩니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다