【问题标题】:More efficient way to loop through tuple and obtain list of lists of transitions from high to low循环遍历元组并获取从高到低的转换列表列表的更有效方法
【发布时间】:2019-03-24 21:48:35
【问题描述】:

我有一个输入整数值的元组,以及一个 high 的值。我想循环并拉出元组中> = high的值的第一个实例对,然后是high的第一个值。一个例子可能会有所帮助:

只保留每个重复高点或低点的第一个高点或第一个低点

例如,如果 max == 100,则输入为 (102, 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)

【问题讨论】:

  • 您只需要一个布尔变量(例如in_high)。如果您发现一个高值并且 in_high 为 False,则使用该值开始新的内部转换,将 in_high 设置为 True。否则,如果值较低且in_high 为 True,则关闭内部转换并更改in_high。其他可能的条件不感兴趣。
  • 在哪个维度上效率更高?代码行? CPU时间?记忆?您可能可以从所有值中减去 100,然后对符号更改采取行动。
  • 谢谢,@michael-butscher
  • 谢谢,@schlenk 你给了我一些值得思考的好东西。
  • @djangomachine 我的回答还是比较短。

标签: python list loops for-loop tuples


【解决方案1】:

您可以使用 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)]

【讨论】:

    【解决方案2】:

    给你:

    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 &gt;= high: 如果我们看起来更高而且更高
      • findh = False 未来看起来更低
      • ret.append([i]) 将另一个列表添加到我们的主列表中,其中只有这个值
    • elif not findh and i &lt; high: 如果我们看起来更低而且它更低
      • findh = True 未来看起来更高
      • ret[-1].append(i)将此值添加到主列表的最后一个列表中

    【讨论】:

      【解决方案3】:

      第一步可能是创建所有“开关”值的列表:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        • 1970-01-01
        • 1970-01-01
        • 2017-11-06
        相关资源
        最近更新 更多