简体   繁体   English

如何确定列表中的数字最初是增加(或保持不变)然后减少(或保持不变)与Python?

[英]How can I determine if the numbers in a list initially increase (or stay the same) and then decrease (or stay the same) with Python?

For example, the digits of 123431 and 4577852 increase and then decrease. 例如, 1234314577852的数字4577852增加然后减少。 I wrote a code that breaks the numbers into a list and is able to tell if all of the digits increase or if all of the digits decrease, but I don't know how to check for digits increasing then decreasing. 我写了一个代码,将数字分成一个列表,并能够判断所有数字是否增加或所有数字是否减少,但我不知道如何检查数字增加然后减少。 How do I extend this? 我该如何延长?

x = int(input("Please enter a number: "))
y = [int(d) for d in str(x)]
def isDecreasing(y):
    for i in range(len(y) - 1):
        if y[i] < y[i + 1]:
            return False
        return True
if isDecreasing(y) == True or sorted(y) == y:
    print("Yes")

Find the maximum element. 找到最大元素。 Break the list into two pieces at that location. 在该位置将列表分成两部分。 Check that the first piece is increasing, the second decreasing. 检查第一件是否增加,第二件减少。

  • For your second example, 4577852 , you find the largest element, 8 . 对于第二个示例4577852 ,您找到最大的元素, 8
  • Break the list in two: 4577 and 852 (the 8 can go in either list, both, or neither). 将列表分为两部分: 4577852 (8可以进入任何列表,两者都可以,或者两者都没有)。
  • Check that 4577 is increasing (okay) and 852 is decreasing (also okay). 检查4577是否正在增加(好), 852正在减少(也没关系)。

Is that enough to get you to a solution? 这足以让你找到解决方案吗?

Seems like a good opportunity to learn about using itertools and generator pipelines. 似乎是学习使用itertools和生成器管道的好机会。 First we make a few simple, decoupled, and reusable components: 首先,我们制作一些简单,分离和可重用的组件:

from itertools import tee, groupby

def digits(n):
    """420 -> 4, 2, 0"""
    for char in str(n):
        yield int(char)

def pairwise(iterable):
    """s -> (s0,s1), (s1,s2), (s2, s3), ..."""
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

def deltas(pairs):
    """2 5 3 4 -> 3, -2, 1"""
    for left, right in pairs:
        yield right - left

def directions(deltas):
    """3 2 2 5 6 -> -1, 0, 1, 1"""
    for delta in deltas:
        yield -1 if delta < 0 else +1 if delta > 0 else 0

def deduper(directions):
    """3 2 2 5 6 2 2 2 -> 3, 2, 5, 6, 2"""
    for key, group in groupby(directions):
        yield key

Then we put the pieces together to solve the wider problem of detecting an "increasing then decreasing number": 然后我们将各个部分放在一起以解决检测“增加然后减少数量”的更广泛问题:

from itertools import zip_longest

def is_inc_dec(stream, expected=(+1, -1)):
    stream = pairwise(stream)
    stream = deltas(stream)
    stream = directions(stream)
    stream = deduper(stream)
    for actual, expected in zip_longest(stream, expected):
        if actual != expected or actual is None or expected is None:
            return False
    else:
        return True

Usage is like this: 用法是这样的:

>>> stream = digits(123431)
>>> is_inc_dec(stream)
True

This solution will short-circuit correctly for a number like: 此解决方案将正确短路,例如:

121111111111111111111111111111111111111111111111111...2 121111111111111111111111111111111111111111111111111 ... 2

I've addressed only the "strictly increasing, and then strictly decreasing" number case. 我只解决了“严格增加,然后严格减少”的案例。 Since this sounds like it might be your homework, I'll leave it as an exercise for you to adapt the code for the "non-decreasing and then non-increasing" case which is mentioned in the question title. 因为这听起来像是你的家庭作业,所以我将把它作为练习让你调整代码以适应问题标题中提到的“不减少然后不增加”的情况。

Split the list at the maximum value, then take the min/ max of the diff of each side: 将列表拆分为最大值,然后取每边差异的最小值/最大值:

import numpy as np

test1 = [1, 2, 3, 4, 5, 8, 7, 3, 1, 0]
test2 = [1, 2, 3, 4, 5, 8, 7, 3, 1, 0, 2, 5]
test3 = [7, 1, 2, 3, 4, 5, 8, 7, 3, 1, 0]
test4 = [1, 2, 3, 4, 5, 8, 8, 7, 3, 1, 0]

def incdec_test(x):
    i = np.array(x).argmax()
    return (np.diff(x[0:i]).min() >= 0) and (np.diff(x[i:-1]).max() <= 0)

for test in [test1, test2, test3, test4]:
    print 'increase then decrease = {}'.format(incdec_test(test))

Results: 结果:

increase then decrease = True
increase then decrease = False
increase then decrease = False
increase then decrease = False

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM