Python列表中根据索引进行优雅的切片

3
我在想,如何以高效优雅的方式基于索引对Python列表进行切片。为了提供一个最小化的示例:
temp = ['a','b','c','d']

index_needed=[0,2]

如何在不使用循环的情况下对列表进行切片?

预期输出:

output_list =['a','c']

我有一种感觉,应该有一种方法,但还没有想出来。有什么建议吗?


可能是理解Python的切片符号的重复问题。 - John Stark
1
@JohnStark 我认为您没有深入了解问题细节。我没有固定的开始、停止或步长参数。我有一个索引列表,可以用它来将它切成两个列表。肯定不是重复的。 - mad_
请在回答之后不要更改问题。这意味着回答者和潜在的回答者都在看一个移动的目标。 - jpp
1
可能是Picking out items from a python list which have specific indexes的重复问题。 - Olivier Melançon
列表只能使用标量或切片进行索引。因此,需要进行某种形式的迭代。而NumPy数组可以使用列表进行索引。 - hpaulj
3个回答

7
首先,需要注意Python中的索引从0开始。因此,你需要的索引将是[0, 2]
然后,您可以使用列表推导式:
temp = ['a', 'b', 'c', 'd']
idx = [0, 2]

res = [temp[i] for i in idx]            # ['a', 'c']

使用内置函数,你会发现map的性能更好:

res = map(temp.__getitem__, idx)        # ['a', 'c']

由于您使用的是Python 2.7,因此这将返回一个列表。对于Python 3.x,您需要将map对象传递给list


如果您想完全避免使用Python级别的循环,则可以使用第三方库,例如NumPy:

import numpy as np

temp = np.array(['a', 'b', 'c', 'd'])
res = temp[idx]

# array(['a', 'c'], 
#       dtype='<U1')

res2 = np.delete(temp, idx)

# array(['b', 'd'], 
#       dtype='<U1')

这将返回一个NumPy数组,你可以通过 res.tolist() 将其转换为列表。


1

Use this :

temp = ['a','b','c','d']

temp[0:4:2]

#Output
['a', 'c']

这里的第一个值是起始索引号,包括在内;第二个值是终止索引号,不包括在内;第三个值是要取的步长。

愉快学习...:)


0
一个将工作推到CPython(参考解释器)的C层的替代方案:
from operator import itemgetter

temp = ['a','b','c','d']

index_needed=[0,2]

output_list = itemgetter(*index_needed)(temp)

该函数返回一个包含值的元组;如果需要返回一个列表,只需将其放在list构造函数中即可:
output_list = list(itemgetter(*index_needed)(temp))

请注意,这只适用于至少需要两个索引的情况;itemgetter是根据其初始化方式而变化的返回类型,当传递一个键来提取时,直接返回该值,当传递多个键时返回一个值的元组。
对于一次性使用来说,它也不是特别高效。更常见的用例是如果您有一个可迭代的序列(通常是tuple,但任何序列都可以),并且不关心它们。例如,对于一个输入为list的情况:
allvalues = [(1, 2, 3, 4),
             (5, 6, 7, 8)]

如果你只想要索引1和3的值,你可以写一个循环,像这样:
for _, x, _, y in allvalues:

在编程中,你可以解包所有的值,但将那些你不关心的值发送给_来表示缺乏兴趣,或者你可以使用itemgettermap将它们剥离到你关心的部分再进行解包:

from future_builtins import map  # Because Py2's map is terrible; not needed on Py3

for x, y in map(itemgetter(1, 3), allvalues):
itemgetter基于的方法不在乎在allvalues的给定元素中是否有超过四个项目,而手动拆包始终需要确切地四个;哪种方法更好主要取决于您的使用情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接