簡體   English   中英

如何將函數應用於列表中的連續值對?

[英]How to apply function to consecutive pairs of values from a list?

我有一本字典

tickers = {'BTC': [200, 149, 98, 44], 'ETH': [200, 320, 405, 460]}

nowprev是列表的元素。

我們將此元素與列表中的上一個元素進行比較。

例如在BTC中:

149(含200)
98和149
44和98

# check state . describe state
def check_state(now, prev):
    state = None
    if now >= prev:
        if now <= 1.5 * prev:
                state = 0
    if now >= 1.5 * prev:
        state = 1
    if now < prev:
        if now * 1.5 >= prev:
               state = 2
    if now * 1.5 < prev:
        state = 3
    return state

我想每天都得到帶有行情自動收錄器和州的新詞典。 第一天沒有狀態,因為第一天沒有前一天。

tickers_state = {'BTC': [None, 3, 3, 3], 'ETH': [None, 1, 0, 0]}

每個股票行情的每一天都有狀態。

我該怎么做?

如果將check_state的輸入參數的順序從def check_state(now, prev):改為def check_state(now, prev): def check_state(prev, now):那么將函數應用於列表的連續值對的問題就變得很容易了。 我想出了以下功能:

import itertools


def apply_pairwise(values,
                   function):
    """
    Applies function to consecutive pairs of elements from an input list
    """
    def pairwise(iterable):
        """
        s -> (s0,s1), (s1,s2), (s2,s3), ...
        """
        a, b = itertools.tee(iterable)
        next(b, None)
        return zip(a, b)

    yield from itertools.chain([None],
                               itertools.starmap(function, pairwise(values)))

用法示例:

>>> btc = [200, 149, 98, 44]
>>> list(apply_pairwise(btc, check_state))
[None, 2, 3, 3]
>>> eth = [200, 320, 405, 460]
>>> list(apply_pairwise(eth, check_state))
[None, 1, 0, 0]

如果您不能撤消輸入:

如果不可能改變輸入的順序,我們可以采用我們的功能:

import itertools


def apply_pairwise(values,
                   function,
                   *,
                   reverse=False):
    """
    Applies function to consecutive pairs of elements from an input list
    """
    def pairwise(iterable):
        """
        s -> (s0,s1), (s1,s2), (s2,s3), ...
        or -> (s1,s0), (s2,s1), (s3,s2), ... if reverse
        """
        a, b = itertools.tee(iterable)
        next(b, None)

        if reverse:
            return zip(b, a)
        return zip(a, b)

    yield from itertools.chain([None],
                               itertools.starmap(function, pairwise(values)))

您可以像這樣使用它:

>>> btc = [200, 149, 98, 44]
>>> list(apply_pairwise(btc, check_state, reverse=True))
[None, 2, 3, 3]
>>> eth = [200, 320, 405, 460]
>>> list(apply_pairwise(eth, check_state, reverse=True))
[None, 1, 0, 0]

說明:

為了獲得連續的元素對,我們可以使用itertools配方中的輔助函數:

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

它是這樣的:

>>> list(pairwise(range(5)))
[(0, 1), (1, 2), (2, 3), (3, 4)]

現在,對於每對元素,我們想應用您的check_state函數。 在這里itertools.starmap可能會有用。 它是這樣的:

>>> list(itertools.starmap(pow, [(2, 3), (2, 10), (10, 3), (3, 4)]))
[8, 1024, 1000, 81]

剩下的唯一事情是在None starmap的值。 starmap一個迭代器時 ,我們可以使用itertools.chain將第一個None與其余元素組合在一起。


PS:將其應用於tickers報價指標的值應該很容易。 我會留給你。

您可以將列表中每對連續的值對與一個循環遍歷列表並使用枚舉啟用對上一個列表項進行比較的函數進行比較。 然后將dict comprehension與函數配合使用,以生成具有比較值的原始dict的映射版本。

在下面的示例中,它從第二個列表項開始循環遍歷列表的一個切片,因此當前元素i值將訪問前一個元素,因為該切片實際上將索引值移位了1。

tickers = {'BTC': [200, 149, 98, 44], 'ETH': [200, 320, 405, 460]}

def check_states(data):
    states = [None]
    for i, n in enumerate(data[1:]):
        state = None
        p = data[i]
        (low, high) = (p / 1.5, p * 1.5)
        if n >= p:
            state = 0 if n <= high else 1
        else:
            state = 2 if n >= low else 3           
        states.append(state)    
    return states

tickers_state = {k: check_states(v) for k, v in tickers.items()}

print(tickers_state)
# OUTPUT
# {'BTC': [None, 2, 3, 3], 'ETH': [None, 1, 0, 0]}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM