Подтвердить что ты не робот

Могу ли я рассчитывать на сохранение порядка в кортежей Python?

У меня есть список дат, из которых я хочу построить сегменты времени. Другими словами, поверните [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)

Вопросы...

  • Могу ли я рассчитывать на tn-1 < tn для любого (tn-1, tn) после того, как я создал их таким образом? (Сохраняется ли заказ?)
  • Хорошо ли копировать исходный список mdtimes со списком? Если нет, то как это сделать?
  • Целью построения этих кортежей является их перебор и сегмент данных с tn-1 и tn. Это разумный подход? то есть.

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

Спасибо

4b9b3361

Ответ 1

  • Порядок набора состоит в том, что вы вставляете значения в кортеж. Они не будут сортироваться, как я думаю, вы спрашиваете. zip снова сохранит порядок, в который вы ввели значения.

  • Это приемлемый метод, но у меня есть 2 альтернативных предложения: используйте модуль copy или используйте dtg1 = mdtimes[:].

  • Звучит разумно.

Ответ 2

Оба list и tuple упорядочены.

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

Ответ 3

Вы можете достичь того же значения с помощью zip:

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

Ответ 4

Вместо: dtg0 = [x for x in mdtimes], dtg0 = mdtimes[:] будет делать, так как вы просто копируете один список в другой. Примечание: начиная с Python 3.3 вы можете просто сказать newlist = oldlist.copy()

Как и для порядка, порядок zip хорошо определен, и оба списка и кортежи - это упорядоченные коллекции, поэтому здесь не должно быть проблем.

Ответ 5

Поворот (x1, x2, x3,...) в [(x1, x2), (x2, x3),...] называется парной комбинацией, и он настолько распространен в шаблоне, что itertools содержит рецепт:

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): 
    ....

Ответ 6

Это ответ на вопрос: "Это разумный подход?" (который, кажется, был проигнорирован всеми).

Резюме.. Вам может понадобиться/нужно поднять свой взгляд, сделав парную вещь из 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, имеющие временную метку < min (mdtimes) или >= max (mdtimes) не будут включены в какой-либо сегмент данных... это намеренно?

Ответ 7

Я не эксперт, но разве вы не в четыре раза увеличиваете свои потребности в памяти, копируя список, а затем создавая новый список пар из двух списков? Почему бы просто не сделать следующее:

dtsegs = [(dtg0[i], dtg0[i+1]) for i in range(len(dtg0)-1)]

Не знаю, что такое "Pythonic".

EDIT: На самом деле, глядя на то, что вам нужно сделать с этим списком кортежей, вы можете просто сделать это [i] и [i + 1] материал прямо на этом уровне и даже не создать эту новую структуру вообще. Я не знаю, сколько дат, с которыми вы имеете дело, хотя, если это небольшое число, я полагаю, это не имеет большого значения.

Для чего это стоит, пара других ответчиков здесь, кажется, неправильно понимает ваш вопрос, хотя я не могу комментировать их сообщения, так как у меня пока нет достаточной репутации:) Решение Ignacio Vazquez-Abrams кажется лучшим для меня, хотя его "следующий (dtg0)", вероятно, должен быть следующим (dtg1) "(?)