복붙노트

[PYTHON] 파이썬 : 간격에서 값으로의 매핑

PYTHON

파이썬 : 간격에서 값으로의 매핑

암묵적으로 간격을 정의하고, 간격에 숫자가 포함되어 있는지 확인한 다음 해당하는 (계산 가능한 방식으로 관련되지 않은) 항목을 반환하는 함수를 리팩토링합니다. 현재 작업을 처리하는 코드는 다음과 같습니다.

if p <= 100:
    return 0
elif p > 100 and p <= 300:
    return 1
elif p > 300 and p <= 500:
    return 2
elif p > 500 and p <= 800:
    return 3
elif p > 800 and p <= 1000:
    return 4
elif p > 1000:
    return 5

IMO는 매우 끔찍한데, 간격과 반환 값이 모두 하드 코드되어 있지 않다는 점에서 부족합니다. 모든 데이터 구조의 사용은 물론 가능합니다.

해결법

  1. ==============================

    1.

    import bisect
    bisect.bisect_left([100,300,500,800,1000], p)
    
  2. ==============================

    2.당신은 이것에 걸릴 수 있습니다 :

    당신은 이것에 걸릴 수 있습니다 :

    def check_mapping(p):
        mapping = [(100, 0), (300, 1), (500, 2)] # Add all your values and returns here
    
        for check, value in mapping:
            if p <= check:
                return value
    
    print check_mapping(12)
    print check_mapping(101)
    print check_mapping(303)
    

    생산 :

    0
    1
    2
    

    언제나처럼 파이썬에서는 더 좋은 방법이있을 것입니다.

  3. ==============================

    3.참으로 끔찍한 일입니다. 하드 코딩을 요구하지 않고 다음과 같이 작성해야합니다.

    참으로 끔찍한 일입니다. 하드 코딩을 요구하지 않고 다음과 같이 작성해야합니다.

    if p <= 100:
        return 0
    elif p <= 300:
        return 1
    elif p <= 500:
        return 2
    elif p <= 800:
        return 3
    elif p <= 1000:
        return 4
    else:
        return 5
    

    다음은 선형 및 2 진 검색을 사용하는 look-up 함수를 작성하는 예제입니다.이 경우 hardcodings 요구 사항이 충족되고 두 테이블에 대해 몇 가지 온 전성 검사가 수행됩니다.

    def make_linear_lookup(keys, values):
        assert sorted(keys) == keys
        assert len(values) == len(keys) + 1
        def f(query):
            return values[sum(1 for key in keys if query > key)]
        return f
    
    import bisect
    def make_bisect_lookup(keys, values):
        assert sorted(keys) == keys
        assert len(values) == len(keys) + 1
        def f(query):
            return values[bisect.bisect_left(keys, query)]
        return f
    
  4. ==============================

    4.다음 행을 따라 뭔가를 시도해보십시오.

    다음 행을 따라 뭔가를 시도해보십시오.

    d = {(None,100): 0, 
        (100,200): 1,
        ...
        (1000, None): 5}
    value = 300 # example value
    for k,v in d.items():
        if (k[0] is None or value > k[0]) and (k[1] is None or value <= k[1]):
            return v
    
  5. ==============================

    5.또 다른 방법 ...

    또 다른 방법 ...

    def which(lst, p): 
        return len([1 for el in lst if p > el])
    
    lst = [100, 300, 500, 800, 1000]
    which(lst, 2)
    which(lst, 101)
    which(lst, 1001)
    
  6. ==============================

    6.

    def which_interval(endpoints, number):
        for n, endpoint in enumerate(endpoints):
            if number <= endpoint:
                return n
            previous = endpoint
        return n + 1
    

    엔드 포인트를 다음과 같이 엔드 포인트의 목록으로 전달하십시오.

    which_interval([100, 300, 500, 800, 1000], 5)
    

    편집하다:

    위는 선형 검색입니다. Glenn Maynard의 대답은 이분법 알고리즘을 사용하므로 성능이 향상됩니다.

  7. from https://stackoverflow.com/questions/1199053/python-mapping-from-intervals-to-values by cc-by-sa and MIT license