【问题标题】:List of lists - Compare neighboring values and IF second elements are the same - take older one列表列表 - 比较相邻值和如果第二个元素相同 - 取旧的
【发布时间】:2021-08-31 18:50:41
【问题描述】:

我正在尝试为这个任务找到一个更优雅的解决方案:我们有一个包含日期和值对的列表列表 -> 需要与邻居值比较,如果值相同 - 我们只选择最旧的日期(但它应该只适用于近邻)。

l = [[datetime.datetime(2021, 1, 1, 0, 0), 0],
    [datetime.datetime(2021, 3, 1, 0, 0), 0],  # need to skipp
    [datetime.datetime(2021, 4, 1, 0, 0), 2],
    [datetime.datetime(2021, 8, 1, 0, 0), 0],  # keep!
    [datetime.datetime(2021, 10, 1, 0, 0), 5]]

预期结果:

[datetime.datetime(2021, 1, 1, 0, 0),
 datetime.datetime(2021, 4, 1, 0, 0),
 datetime.datetime(2021, 8, 1, 0, 0),
 datetime.datetime(2021, 10, 1, 0, 0)]

请看一个例​​子以及到目前为止我是如何解决它的。任何关于如何优化它的想法都非常感谢!

def get_dates_1():  # solution 1 with reverse
    l = [[datetime.datetime(2021, 1, 1, 0, 0), 0],
         [datetime.datetime(2021, 3, 1, 0, 0), 0],   # need to skip
         [datetime.datetime(2021, 4, 1, 0, 0), 2],
         [datetime.datetime(2021, 8, 1, 0, 0), 5],
         [datetime.datetime(2021, 10, 1, 0, 0), 5]]  # need to skip

    l.reverse()
    dates = []

    for i in range(len(l)):
        if i < len(l) - 1:
            if l[i][1] != l[i + 1][1]:
                dates.append(l[i][0])
        else:
            dates.append(l[i][0])
    return list(reversed(dates))

def get_dates_2():   # solution 2 w/o reverse
    l = [[datetime.datetime(2021, 1, 1, 0, 0), 0],
         [datetime.datetime(2021, 3, 1, 0, 0), 0],   # need to skip
         [datetime.datetime(2021, 4, 1, 0, 0), 2],
         [datetime.datetime(2021, 8, 1, 0, 0), 5],
         [datetime.datetime(2021, 10, 1, 0, 0), 5]]  # need to skip

    l.sort(key=lambda x: x[0])
    result = [l[0]]
    for date, value in l:
        if value != result[-1][1]:
            result.append([date, value])

    dates = [x for x, _ in result]
    return dates

预期:

[datetime.datetime(2021, 1, 1, 0, 0),
 datetime.datetime(2021, 4, 1, 0, 0),
 datetime.datetime(2021, 8, 1, 0, 0)]

【问题讨论】:

  • 你可以有超过 2 个具有相同值的相邻元素,还是它们总是成对的?
  • itertools.groupby() 对此很有用。
  • 嗨@Barman!完成 :) 在 l 结构上 - 它总是成对的 [date, int]。
  • 不,我的意思是你可以有超过 2 个具有相同 int 值的相邻元素吗?
  • 啊,是的,有可能 l = [[datetime.datetime(2021, 1, 1, 0, 0), 0], [datetime.datetime(2021, 3, 1, 0, 0) , 0], [datetime.datetime(2021, 4, 1, 0, 0), 0], [datetime.datetime(2021, 8, 1, 0, 0), 0], [datetime.datetime(2021, 10) , 1, 0, 0), 5]] -> 期望从这里开始的第一个和最后一个日期

标签: python compare


【解决方案1】:

我的解决方案使用itertools.groupyby 将列表分成子组。

import datetime
import itertools


def get_dates():

    my_list = [
        [datetime.datetime(2021, 3, 1, 0, 0), 0],
        [datetime.datetime(2021, 1, 1, 0, 0), 0],

        [datetime.datetime(2021, 4, 1, 0, 0), 2],

        [datetime.datetime(2021, 8, 1, 0, 0), 5],
        [datetime.datetime(2021, 10, 1, 0, 0), 5]
    ]

    result = [
        # Within each group, sort, and pick out the first (oldest) list
        sorted(group)[0][0]

        # Group the sub-lists by the second element
        for _, group in itertools.groupby(my_list, key=lambda li: li[1])
    ]

    return result


for x in get_dates():
    print(x)

输出:

[datetime.datetime(2021, 1, 1, 0, 0), 0]
[datetime.datetime(2021, 4, 1, 0, 0), 2]
[datetime.datetime(2021, 8, 1, 0, 0), 5]

【讨论】:

  • 不错的选择!谢谢@Hai Vu!
猜你喜欢
  • 2019-05-05
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 2021-04-28
  • 2011-01-17
  • 1970-01-01
相关资源
最近更新 更多