我可以指望在Python元组中保存顺序吗?

时间:2010-12-01 16:30:23

标签: python list tuples

我有一个日期时间列表,我想从中构建时间段。换句话说,将[t0, t1, ... tn]转换为[(t0,t1),(t1,t2),...,(tn-1, tn)]。我这样做了:

# start by sorting list of datetimes
mdtimes.sort()
# construct tuples which represent possible start and end dates

# left edges
dtg0 = [x for x in mdtimes]
dtg0.pop()

# right edges
dtg1 = [x for x in mdtimes]
dtg1.reverse()
dtg1.pop()
dtg1.sort()

dtsegs = zip(dtg0,dtg1)

...问题

  1. 我可以依靠tn-1<在我用这种方式创建它们之后的任何(tn-1,tn)? (订购保存吗?)
  2. 使用列表推导复制原始mdtimes列表是一种好习惯吗?如果不是应该怎么做?
  3. 构建这些元组的目的是迭代它们并使用tn-1tn对数据集进行细分。这是一种合理的方法吗?即。

    datasegment = [x for x in bigdata if ( (x['datetime'] > tleft) and (x['datetime'] < tright))] 
    
  4. 由于

7 个答案:

答案 0 :(得分:18)

listtuple都已订购。

dtg0, dtg1 = itertools.tee(mdtimes)
next(dtg0)
dtsegs = zip(dtg0, dtg1)

答案 1 :(得分:16)

  1. 元组顺序是在元组中插入值时的顺序。我认为你不会按照我的要求对它们进行分类。 zip将再次保留您插入值的顺序。

  2. 这是一种可接受的方法,但我有2个备用建议:使用copy模块,或使用dtg1 = mdtimes[:]

  3. 听起来很合理。

答案 2 :(得分:5)

您可以使用zip实现相同的目标:

>>> l = ["t0", "t1", "t2", "t3", "t4", "t5", "t6"]
>>> zip(l[::2], l[1::2])
[('t0', 't1'), ('t2', 't3'), ('t4', 't5')]

答案 3 :(得分:2)

而不是:dtg0 = [x for x in mdtimes]dtg0 = mdtimes[:]会这样做,因为您只需将一个列表复制到另一个列表中。注意:从Python 3.3开始,您可以说newlist = oldlist.copy()

至于订单,zip的订单定义明确,列表和元组都是有序集合,所以你应该没有问题。

答案 4 :(得分:2)

将(x1,x2,x3,...)转换为[(x1,x2),(x2,x3),...]称为成对组合,它是如此常见的模式{{3文档提供了一个配方:

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

for ta, tb in pairwise(mdtimes): 
    ....

答案 5 :(得分:2)

这是对“这是一种合理的方法吗?”这个问题的回答。 (似乎所有人都忽略了这一点。)

摘要:您可能希望/需要将目标从mdtimes提升为包含问题(分段bigdata)。

<强>详情:

结果的理想用法表示为:

datasegment = [x for x in bigdata if ( (x['datetime'] > tleft) and (x['datetime'] < tright))] 

更好地表达为:

datasegment = [x for x in bigdata if tleft < x['datetime'] < tright] 

请注意,就此而言,它不包括任何时间戳正好等于其中一个边界点的情况,所以我们将其更改为:

datasegment = [x for x in bigdata if tleft <= x['datetime'] < tright]

但那会出现在循环中:

for tleft, tright in dtsegs:
    datasegment = [x for x in bigdata if tleft <= x['datetime'] < tright]
    do_something_with(datasegment)

糟糕!这需要花费时间与len(bigdata) * len(dtsegs)成比例...... len(bigdata)len(dtsegs)的可能值是多少?

如果bigdata已排序,您要执行的操作可以与N成比例,其中N = len(bigdata)bigdata。如果N * log(N)尚未排序,则可以按时间与bigdata成比例进行排序。

你可能想问另一个问题......

值得指出的是{{1}}中有时间戳&lt; {{1}}的所有项目。 min(mdtimes)或&gt; = max(mdtimes)不会包含在任何数据段中...这是故意的吗?

答案 6 :(得分:1)

我不是专家,但是你不是通过复制列表然后从两个列表中创建一个新的对列表来使你的内存需求翻两番吗?为什么不这样做:

dtsegs = [(dtg0[i], dtg0[i+1]) for i in range(len(dtg0)-1)]
但不过,不管怎么说“恐怖”也是如此。

编辑:实际上,看看你需要对这个元组列表做什么,你可以直接在那个级别做这个[i]和[i + 1]的东西,甚至根本不创建这个新结构。我不知道你要处理的日期有多少 - 如果它的数量很少,我认为这并不重要。

对于它的价值,这里的其他几个回答者似乎误解了你的问题,虽然我不能评论他们的帖子,因为我还没有足够的声誉:) Ignacio Vazquez-Abrams的解决方案似乎是最好的对我来说,虽然他的“下一个(dtg0)”应该是“下一个(dtg1)”(?)