使用 python 中的索引创建一个包含列表子集的新列表

问题描述 投票:0回答:5

一览:

a = ['a', 'b', 'c', 3, 4, 'd', 6, 7, 8]

我想要一个使用 using

a[0:2],a[4], a[6:]
,

子集的列表

那是我想要一个列表

['a', 'b', 4, 6, 7, 8]

python list indexing subset
5个回答
44
投票

假设

a = ['a', 'b', 'c', 3, 4, 'd', 6, 7, 8]

索引列表存储在

b= [0, 1, 2, 4, 6, 7, 8]

然后一个简单的单线解决方案将是

c = [a[i] for i in b]

35
投票

尝试

new_list = a[0:2] + [a[4]] + a[6:]
.

或者更一般地说,是这样的:

from itertools import chain
new_list = list(chain(a[0:2], [a[4]], a[6:]))

这也适用于其他序列,并且可能会更快。

或者你可以这样做:

def chain_elements_or_slices(*elements_or_slices):
    new_list = []
    for i in elements_or_slices:
        if isinstance(i, list):
            new_list.extend(i)
        else:
            new_list.append(i)
    return new_list

new_list = chain_elements_or_slices(a[0:2], a[4], a[6:])

但是请注意,如果列表中的某些元素本身就是列表,这会导致问题。 要解决此问题,请使用先前的解决方案之一,或将

a[4]
替换为
a[4:5]
(或更一般地,将
a[n]
替换为
a[n:n+1]
)。


1
投票

以下定义可能比第一个提出的解决方案更有效

def new_list_from_intervals(original_list, *intervals):
    n = sum(j - i for i, j in intervals)
    new_list = [None] * n
    index = 0
    for i, j in intervals :
        for k in range(i, j) :
            new_list[index] = original_list[k]
            index += 1

    return new_list

然后你可以像下面这样使用它

new_list = new_list_from_intervals(original_list, (0,2), (4,5), (6, len(original_list)))

1
投票

这个帖子已经有几年了,我不知道当时有没有这个方法,但是我在 2022 年找到的最快的解决方案目前没有在答案中提到。 我的示例列表包含从 1 到 6 的整数,我想从此列表中检索 4 项。

我在安装了 Python 3.7.4 的 Windows 10 系统上使用了 Jupyter Notebook / iPython 的 %timeit 功能。

我添加了一个 numpy 方法只是为了看看它有多快。原始问题的混合类型集合可能需要更多时间。

最快的解决方案似乎是来自 operator 模块(标准库)的 itemgetter。如果返回的是元组还是列表并不重要,请按原样使用 itemgetter 或以其他方式使用列表转换。这两种情况都比其他解决方案更快。

from itertools import chain
import numpy as np
from operator import itemgetter
# 
my_list = [1,2,3,4,5,6]
item_indices = [2, 0, 1, 5]
# 
%timeit itemgetter(*item_indices)(my_list)
%timeit list(itemgetter(*item_indices)(my_list))
%timeit [my_list[item] for item in item_indices]
%timeit list(np.array(my_list)[item_indices])
%timeit list(chain(my_list[2:3], my_list[0:1], my_list[1:2], my_list[5:6]))

输出为:

184 ns ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
251 ns ± 11.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
283 ns ± 85.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
4.3 µs ± 260 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
663 ns ± 49.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

根据列表的大小和我们要提取的项目数量,我会对哪种解决方案最快的可能偏差感兴趣,但这是我当前项目的典型用例。 如果有人有时间对此进行进一步调查,请告诉我。


0
投票

我有类似的要求,但我没有使用切片,而是想引用索引。 这是我所做的:

numbers = ['3.1', '2,832', '4.5', '534,459', '8.2', '2,176,777', '8.6']
indices = [2, 3, 4, 6]

subset = [numbers[i] for i in indices]

print(subset)
© www.soinside.com 2019 - 2024. All rights reserved.