【问题标题】:What is the Pythonic way to get last not-None value from a list从列表中获取最后一个非无值的 Pythonic 方法是什么
【发布时间】:2015-04-30 16:38:50
【问题描述】:

以下代码从日期值的有序列表中获取最后一个当前值:

def test_get_last_value(self):
    dated_optional_values = [(datetime.datetime(2015, 2, 23), None),
                    (datetime.datetime(2015, 2, 24), 1.23),
                    (datetime.datetime(2015, 2, 25), None),
                    (datetime.datetime(2015, 2, 26), 2.34),
                    (datetime.datetime(2015, 2, 27), None),
                    ]
    present_values = [dated_optional_value[1] for dated_optional_value in dated_optional_values
        if dated_optional_value[1] is not None]
    last_present_value = present_values[-1]
    print('last_present_value=', last_present_value)

我可以很容易地编写一个循环,从列表的末尾开始,然后迭代,直到找到一个值。

有没有更 Pythonic 的方式来实现这一点?

【问题讨论】:

  • 使用reversed()find the first non-None value
  • 我不认为reversed() 比您已有的解决方案更好。将列表过滤到新列表中是常见的和“pythonic”。
  • @tdelaney: reversed() 允许您避免在结尾附近有非None 值时不必要地枚举所有值。与any()all() 函数一样具有短路行为。在 OP 的情况下这并不重要,因为列表很短。但我没有看到任何迹象表明标题中应该有一个非常小的列表。

标签: python python-2.7


【解决方案1】:
next((dop[1] for dop in reversed(date_optional_values) if dop[1] is not None), None)

您可以将最终的None 替换为您喜欢的任何其他值,以返回每个值都是None 的情况。或者在它们都是None 的情况下省略该参数以引发异常。

【讨论】:

    【解决方案2】:

    也许:

    last_present_value = next(x for x in reversed(dated_optional_values) 
                              if x[1] is not None)
    

    【讨论】:

      【解决方案3】:

      考虑单独的步骤可能会很好:

      1. 您想要第二列 (x[1])

        def column(data, index): return [x[index] for x in data]

      2. 你想过滤掉None

        def notNone(data): return [x for x in data if x is not None]

      3. 你想要最后一个元素

        def last(data): return data[-1]

      那么你的问题就变成了

      last_preset_value = last(notNone(column(data, 1)))
      

      【讨论】:

        【解决方案4】:

        您还可以将其概括为采用 last nNone 值 - 例如,采用最后 2 个非空白:

        from itertools import islice
        
        candidates = (el[1] for el in reversed(dated_optional_values) if el[1] is not None)
        last_n = list(islice(candidates, 2)) or []
        

        另外,如果您没有Sized 容器,例如列表,并且有一些任意可迭代的,您可以使用固定大小的collections.deque,例如:

        from collections import deque
        
        candidates = (el[1] for el in dated_optional_values if el[1] is not None)
        d = deque([], 2)
        d.extendleft(candidates)
        matches = list(d) or []
        

        这两个选项都返回:

        [2.34, 1.23]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-12-18
          • 1970-01-01
          • 1970-01-01
          • 2012-04-20
          • 1970-01-01
          • 2010-12-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多