Разделите список на части на основе ряда индексов в Python

Internet Explorer 8 и более старый не поддерживает надлежащий тип MIME для XHTML, application/xhtml+xml. Если Вы будете служить XHTML в качестве text/html, к которому Вы имеете для этих более старых версий Internet Explorer, чтобы сделать что-либо, это будет интерпретироваться как HTML 4.01. Можно только использовать короткий синтаксис с любым элементом, который разрешает закрывающему тэгу быть опущенным. Посмотрите Спецификация .

HTML 4.01, 'краткая форма' XML интерпретируется как атрибут, названный/, который (потому что существует, не равняется знаку), интерпретируется как наличие неявного значения "/". Это строго неправильно в HTML 4.01 - необъявленные атрибуты не разрешены - но браузеры проигнорируют его.

IE9 и позже XHTML 5 поддержки, подаваемый с application/xhtml+xml.

50
задан drjeep 3 August 2009 в 01:31
поделиться

9 ответов

Это простейшее и наиболее питоническое решение, которое я могу придумать:

def partition(alist, indices):
    return [alist[i:j] for i, j in zip([0]+indices, indices+[None])]

если входные данные очень большие, то решение итераторов должно быть более удобным:

from itertools import izip, chain
def partition(alist, indices):
    pairs = izip(chain([0], indices), chain(indices, [None]))
    return (alist[i:j] for i, j in pairs)

и, конечно же, решение для очень, очень ленивого парня (если вы не против получить массивы вместо списков, но в любом случае вы всегда можете вернуть их в списки):

import numpy
partition = numpy.split
48
ответ дан 7 November 2019 в 11:04
поделиться

Мне было бы интересно увидеть более питонический способ сделать это. Но это хреновое решение. Вам нужно добавить проверку для пустого списка индексов.

Что-то вроде:

indexes = [5, 12, 17]
list = range(20)

output = []
prev = 0

for index in indexes:
    output.append(list[prev:index])
    prev = index

output.append(list[indexes[-1]:])

print output

производит

[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16], [17, 18, 19]]
9
ответ дан 7 November 2019 в 11:04
поделиться
indices = [5, 12, 17]
input = range(20)
output = []

reduce(lambda x, y: output.append(input[x:y]) or y, indices + [len(input)], 0)
print output
2
ответ дан 7 November 2019 в 11:04
поделиться

Это все, что я мог придумать

def partition(list_, indexes):
    if indexes[0] != 0:
        indexes = [0] + indexes
    if indexes[-1] != len(list_):
        indexes = indexes + [len(list_)]
    return [ list_[a:b] for (a,b) in zip(indexes[:-1], indexes[1:])]
0
ответ дан 7 November 2019 в 11:04
поделиться

Cide's делает три копии array: [0] + индексы копируются, ([0] + индексы) + [] копируются снова, а индексы [: - 1] копируются в третий раз. Il-Bhima делает пять копий. (Я, конечно, не считаю возвращаемое значение.)

Их можно уменьшить (izip, islice), но вот версия с нулевым копированием:

def iterate_pairs(lst, indexes):
    prev = 0
    for i in indexes:
        yield prev, i
        prev = i
    yield prev, len(lst)

def partition(lst, indexes):
    for first, last in iterate_pairs(lst, indexes):
        yield lst[first:last]

indexes = [5, 12, 17]
lst = range(20)

print [l for l in partition(lst, indexes)]

Конечно, копии массива довольно дешевы (собственный код) по сравнению с интерпретируемым Python, но у этого есть еще одно преимущество: его легко повторно использовать, напрямую изменять данные:

for first, last in iterate_pairs(lst, indexes):
    for i in range(first, last):
        lst[i] = first
print lst
# [0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12, 12, 17, 17, 17]

(Вот почему я передал индексы в iterate_pairs. Если вас это не волнует,

0
ответ дан 7 November 2019 в 11:04
поделиться

Вот еще один ответ .

def partition(l, indexes):
    result, indexes = [], indexes+[len(l)]
    reduce(lambda x, y: result.append(l[x:y]) or y, indexes, 0)
    return result

Он поддерживает отрицательные индексы и т. Д.

>>> partition([1,2,3,4,5], [1, -1])
[[1], [2, 3, 4], [5]]
>>> 
0
ответ дан 7 November 2019 в 11:04
поделиться

Множественное число индексов - это индексы. Стремление к простоте / удобочитаемости.

indices = [5, 12, 17]
input = range(20)
output = []

for i in reversed(indices):
    output.append(input[i:])
    input[i:] = []
output.append(input)

while len(output):
    print output.pop()
-1
ответ дан 7 November 2019 в 11:04
поделиться
>>> def burst_seq(seq, indices):
...    startpos = 0
...    for index in indices:
...       yield seq[startpos:index]
...       startpos = index
...    yield seq[startpos:]
...
>>> list(burst_seq(range(20), [5, 12, 17]))
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16], [17, 18, 19]]
>>> list(burst_seq(range(20), []))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
>>> list(burst_seq(range(0), [5, 12, 17]))
[[], [], [], []]
>>>

Maxima mea culpa: он использует оператор для , и он не использует такие вещи whizzbang, как itertools, zip (), None в качестве дозорного, понимание списка, ...

; -)

4
ответ дан 7 November 2019 в 11:04
поделиться

Мое решение похоже на решение Иль-Бхимы.

>>> def parts(list_, indices):
...     indices = [0]+indices+[len(list_)]
...     return [list_[v:indices[k+1]] for k, v in enumerate(indices[:-1])]

Альтернативный подход

Если вы готовы немного изменить способ ввода индексов, с абсолютных индексов на относительные (то есть, с [5, 12, 17] на [5, 7, 5] , приведенный ниже код также даст вам желаемый результат, хотя он не создает списки промежуточных звеньев.

>>> from itertools import islice
>>> def parts(list_, indices):
...     i = iter(list_)
...     return [list(islice(i, n)) for n in chain(indices, [None])]
7
ответ дан 7 November 2019 в 11:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: