多个日期时间列表的Python交集

时间:2014-08-19 19:57:04

标签: python list datetime intersection

我正在尝试找到5个datetime对象列表的交集列表。我知道列表问题的交集在这里已经出现了很多,但是我的代码没有按预期执行(就像其他问题中那样)。

以下是5个列表中的前3个元素,最后列表的确切长度。

[datetime.datetime(2014, 8, 14, 19, 25, 6), datetime.datetime(2014, 8, 14, 19, 25, 7), datetime.datetime(2014, 8, 14, 19, 25, 9)] # length 38790
[datetime.datetime(2014, 8, 14, 19, 25, 6), datetime.datetime(2014, 8, 14, 19, 25, 7), datetime.datetime(2014, 8, 14, 19, 25, 9)] # length 38818
[datetime.datetime(2014, 8, 14, 19, 25, 6), datetime.datetime(2014, 8, 14, 19, 25, 7), datetime.datetime(2014, 8, 14, 19, 25, 9)] # length 38959
[datetime.datetime(2014, 8, 14, 19, 25, 6), datetime.datetime(2014, 8, 14, 19, 25, 7), datetime.datetime(2014, 8, 14, 19, 25, 9)] # length 38802
[datetime.datetime(2014, 8, 14, 19, 25, 6), datetime.datetime(2014, 8, 14, 19, 25, 7), datetime.datetime(2014, 8, 14, 19, 25, 9)] # length 40415

我已经列出了名为times的列表。我尝试了两种交叉方法。

方法1

intersection = times[0] # make intersection the first list
for i in range(len(times)):
    if i == 0:
        continue
    intersection = [val for val in intersection if val in times[i]]

此方法会生成一个长度为20189的列表,并需要104秒才能运行。

方法2

intersection = times[0] # make intersection the first list
for i in range(len(times)):
    if i == 0:
        continue
    intersection = list(set(intersection) & set(times[i]))

此方法生成一个长度为20148的列表,运行时间为0.1秒。

我遇到了2个问题。第一个问题是两种方法产生不同大小的交叉点,我不知道为什么。另一个问题是日期时间对象datetime.datetime(2014, 8, 14, 19, 25, 6)显然在所有5个列表中(见上文),但当我print (datetime.datetime(2014, 8, 14, 19, 25, 6) in intersection)时它返回False。

4 个答案:

答案 0 :(得分:0)

列表可能包含重复项,这可能导致长度不一致。要避免这些重复,您可以将每个日期时间列表转换为一组:

map(set, times)

这将为您提供一组集合(删除重复次数)。要查找交叉点,您可以使用set.intersection

intersection = set.intersection(*map(set, times))

以您的示例为例,交集将是此设置:

set([datetime.datetime(2014, 8, 14, 19, 25, 9), datetime.datetime(2014, 8, 14, 19, 25, 6), datetime.datetime(2014, 8, 14, 19, 25, 7)])

答案 1 :(得分:0)

您的第一个列表times[0]包含重复元素;这是不一致的原因。如果您在第一个代码段中执行intersection = list(set(times[0])),问题就会消失。

至于你的第二个代码,如果你从不在列表和集之间进行更改,代码会更快:

intersection = set(times[0]) # make a set of the first list
for timeset in times[1:]:
    intersection.intersection_update(timeset)

# if necessary make into a list again
intersection = list(intersection)

实际上,因为intersection支持多个迭代作为单独的参数。您只需用以下代码替换所有代码:

intersection = set(times[0]).intersection(*times[1:])

对于in intersection问题,实例是实际的datetime.datetime还是只是假装?至少时间戳似乎不是时区感知

答案 2 :(得分:0)

可能会有重复的时间,你可以这样做:

Python3:

import functools
result = functools.reduce(lambda x, y: set(x) & set(y), times)

Python2:

result = reduce(lambda x, y: set(x) & set(y), times)

答案 3 :(得分:0)

intersection = set(*times[:1]).intersection(*times[1:])