Список разделов по индексам - PullRequest
1 голос
/ 13 октября 2019

Итак, есть список List = ['a', 'b', 'c', 'd', 'e'] и список индексов Indices = [1, 2, 4].

Я хочу разделить список на два списка: один, содержащий элементы в Indices (['b', 'c', 'e']), и другой, содержащий все остальные элементы (['a', 'd').

ДляПервый список У меня уже есть простое решение.

In_List = [List[i] for i in Indices]

Однако, для другого списка у меня есть только довольно уродливое решение

Out_List = [List[i] for i in range(len(List)) if i not in Indices]

Решение, которое у меня есть, работает, но оноПохоже, должен быть более элегантный способ сделать это.

Есть предложения?

Редактировать / обновить

Кажется, что есть 3 предложения:

Один цикл по индексам:

    In_List = []
    Out_List = []
    for i in range(len(List)):
        if i in Indices:
            In_List.append(List[i])
        else:
            Out_List.append(List[i])

Цикл через перечисление:

    In_List = []
    Out_List = []
    for index, value in enumerate(List):
        if index in Indices:
            In_List += [value]
        else:
            Out_List += [value]

Использование Numpy:

    Indices = np.array(Indices)
    List = np.array(List)
    In_List = list(List[Indices])
    Out_List = list(np.delete(List, Indices))

Спасибо всем за предложение.

Я взял эти три решения и свое первоначальное решение и сравнил их для списков разного размера (range(10, 1000, 10)), каждый раз выбирая одну восьмую из элементов - в среднем более 100 повторений. Кажется, что понимание списка немного быстрее, чем циклы, но не значительно. Numpy, кажется, медленнее для коротких списков, но абсолютно разбивает другие решения для больших списков.

Редактировать / обновить : заставил numpy-версию также возвращать список, а затем обновил график.

enter image description here

Ответы [ 5 ]

3 голосов
/ 13 октября 2019

Это не более элегантно, но, по крайней мере, вы избегаете двух циклов for (что весьма неэффективно, если вы работаете с большим количеством данных).

In_List = []
Out_List = []
for i in range(len(List)):
    if i in Indices:
        In_List.append(List[i])
    else:
        Out_List.append(List[i])

Редактировать: Вы также можете написать приведенный выше код в одном фрагменте, но он не совсем читабелен:

in_List = []
out_List = []
[in_List.append(List[j]) if j in Indices else out_List.append(List[j]) for j in range(len(List))] 

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

import numpy as np
Indices = np.array(Indices)
List = np.array(List)
In_List = List[Indices]
Out_List = np.delete(List, Indices) 
1 голос
/ 13 октября 2019

это также будет работать:

List = ['a', 'b', 'c', 'd', 'e']
Indices = [1, 2, 4]

ret = ([], [])
for i, item in enumerate(List):
    ret[i in Indices].append(item)
Out_List, In_List = ret

, где я использую i in Indices в качестве индекса для вложенного кортежа ret, а затем распаковываю его в последней строке, чтобы получить In_List и Out_List.

0 голосов
/ 13 октября 2019

Использование логической маски NumPy (с np.in1d ​​):

import numpy as np

lst = np.array(['a', 'b', 'c', 'd', 'e'])
indices = np.array([1, 2, 4])
m = np.in1d(range(lst.size), indices)
in_list, out_list = lst[m], lst[~m]    # ['b' 'c' 'e'] ['a' 'd']
0 голосов
/ 13 октября 2019

Вы можете использовать itemgetter из операторского модуля:

from operator import itemgetter

my_list = ['a', 'b', 'c', 'd', 'e']

in_indices = [1, 2, 3]
out_indices = set(range(len(my_list))).difference(in_indices)
# also you ca use:
# out_indices = [0, 4]

in_list = list(itemgetter(*in_indices)(my_list ))
out_list = list(itemgetter(*out_indices)(my_list ))

print(in_list)
print(out_list)

вывод:

['b', 'c', 'd']
['a', 'e']
0 голосов
/ 13 октября 2019

Вы можете добиться того же результата только одним разбором вашего List, используя метод enumerate:

List = ['a', 'b', 'c', 'd', 'e']
Indices = [1, 2, 4]

In_List = []
Out_List = []
for index, value in enumerate(List):
    if index in Indices:
        In_List += [value]
    else:
        Out_List += [value]

Было бы еще эффективнее, если бы ваша переменная Indices была set вместо list.

...