Более эффективный способ перебрать кортеж и получить список списков переходов от высокого к низкому - PullRequest
1 голос
/ 25 марта 2019

У меня есть кортеж входных целочисленных значений и значение high .Я хочу перебрать и вытащить пары первого экземпляра значения в кортеже> = high , а затем первого значения <<em> high .Пример может помочь:

Сохранять только первый максимум или первый минимум каждого повторяющегося максимума или минимума

Например, если max == 100, а вход равен ( 102 *)1012 *, 109, 120, 80 , 40, 30, 200 , 90 )

вывод должен быть [[102, 80], [200, 90]]

items = (102, 109, 120, 80, 40, 30, 200, 90)
high = 100
started = False  # Used to ensure we start with high values first
currently_on_highs = True
first_val_high = True
first_val_low = True
transitions = []
inner_transition = []

for item in items:
    if item >= high:
        started = True
        currently_on_highs = True
        if first_val_high:
            first_val_high = False
            first_val_low = True
            inner_transition.append(item)
    else:
        if started:
            currently_on_highs = False
            if first_val_low:
                first_val_high = True
                first_val_low = False
                inner_transition.append(item)
                transitions.append(inner_transition)
                inner_transition = []

print(transitions)

Вот гораздо лучший результат после предложения @ michael-butscher

items = (102, 109, 120, 80, 40, 30, 200, 90)
high = 100
in_high = False
transitions = []
inner_transition = []

for item in items:
    if item >= high and not in_high:
        in_high = True
        inner_transition.append(item)
    elif item < high and in_high:
        in_high = False
        inner_transition.append(item)
        transitions.append(inner_transition)
        inner_transition = []

print(transitions)

Ответы [ 3 ]

1 голос
/ 25 марта 2019

Вы можете легко сделать это с помощью zip, сместив элементы на одну запись, чтобы сравнить каждый из них со своим предшественником:

items  = (102, 109, 120, 80, 40, 30, 200, 90)
high   = 100
bounds = [ num for prev,num in zip((high-1,)+items,items) if (num<high)^(prev<high) ] 
result = list(zip(bounds[::2],bounds[1::2]))
print(result) # [(102, 80), (200, 90)]
0 голосов
/ 25 марта 2019

Первым шагом может быть создание списка всех значений «переключателя»:

items = (102, 109, 120, 80, 40, 30, 200, 90)
high = 100

res = []
last = high-1
for x in items:
    if last < high <= x or x <= high < last: 
        res.append(x) 
    last = x

, затем вы можете построить пары:

res = [(res[i], res[i+1]) for i in range(0, len(res), 2)]
0 голосов
/ 25 марта 2019

Вот, пожалуйста:

items = (102, 109, 120, 80, 40, 30, 200, 90)
high = 100

ret = []
findh = True
for i in items:
    if findh and i >= high:
        findh = False
        ret.append([i])
    elif not findh and i < high:
        findh = True
        ret[-1].append(i)

print(ret)

Объяснение:

  • ret = [] что мы добавим пары к
  • findh = Trueили нет, мы должны искать более высокое значение
  • if findh and i >= high:, если мы смотрим выше, и оно выше
    • findh = False смотреть в будущем ниже
    • ret.append([i]) добавитьеще один список в нашем мастер-списке, с этим значением в
  • elif not findh and i < high:, если мы смотрим ниже, а ниже
    • findh = True смотрим выше в будущем
    • ret[-1].append(i) добавить это значение в последний список в основном списке
...