如何对列表中的连续值对应用函数?

2024-05-14 15:34:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典

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

now和{}是列表的元素。在

我们比较这个元素和列表中的前一个元素。在

例如在BTC中:

149 with 200
98 with 149
44 with 98

^{pr2}$

我想买一本每天都有行情和状态的新词典。 第一天没有状态,因为第一天没有前一天。在

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

元素在每个股票代码的每一天都有状态。在

我该怎么做?在


Tags: none元素列表字典状态withnow行情
2条回答

如果将check_state的输入参数的顺序从def check_state(now, prev):颠倒到{},那么将函数应用于列表中连续的值对的问题就变得相当容易了。我想出了以下函数:

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)))

用法示例:

^{pr2}$

如果无法反转输入:

如果不可能改变输入顺序,我们可以采用我们的函数:

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]

说明:

为了获得连续的元素对,我们可以使用^{}配方中的helper函数:

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函数。这里^{}可能很有用。它是这样工作的:

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

唯一剩下的事情是将starmap产生的值加上None。当starmap生成一个iterator时,我们可以使用^{}将第一个{}与其余元素组合起来。在


注:将此应用于您的tickersdict的值应该很容易。我把它留给你。在

您可以使用一个函数来比较列表中的每个连续值对,该函数循环遍历列表并使用enumerate启用对上一个列表项进行比较的访问。然后将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]}

相关问题 更多 >

    热门问题