【问题标题】:Elegant slicing in python list based on index基于索引的python列表中的优雅切片
【发布时间】:2019-01-29 23:18:52
【问题描述】:

我想知道基于索引对 python 列表进行切片的一种高效优雅的方法是什么。为了提供一个最小的例子:

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

index_needed=[0,2]

如何在没有循环的情况下对列表进行切片?

预期输出

output_list =['a','c']

我感觉会有办法,但还没有想出办法。有什么建议吗?

【问题讨论】:

  • @JohnStark 我认为您没有深入了解问题的细节。我没有固定的开始、停止或步进参数。我有一个索引列表,我可以用它来将它分成两个列表。绝对不是重复的
  • 一旦您有答案,请不要更改问题。这意味着回答者和潜在答案正在寻找一个移动的目标。
  • 列表只能使用标量或切片进行索引。所以需要某种迭代。它是可以用列表索引的 numpy 数组。

标签: python arrays python-2.7 list numpy


【解决方案1】:

首先,请注意 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 级循环,您可能希望使用 3rd 方库,例如 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() 将其转换为列表。

【讨论】:

    【解决方案2】:

    使用这个:

    temp = ['a','b','c','d']
    
    temp[0:4:2]
    
    #Output
    ['a', 'c']
    

    这里第一个值是起始索引号,即(包含)第二个值是结束索引号,即(排除)第三个值是要采取的(步骤)。

    快乐学习...:)

    【讨论】:

      【解决方案3】:

      将工作推送到 CPython(参考解释器)上的 C 层的替代方案:

      from operator import itemgetter
      
      temp = ['a','b','c','d']
      
      index_needed=[0,2]
      
      output_list = itemgetter(*index_needed)(temp)
      

      返回值的tuple;如果list 是必要的,只需将list 构造函数包装起来:

      output_list = list(itemgetter(*index_needed)(temp))
      

      请注意,这仅在您需要至少两个索引时才能正常工作; itemgetter 是可变的返回类型,基于它的初始化方式,当它传递一个键来拉取时直接返回值,当传递多个键时返回值的tuple

      一次性使用也不是特别有效。一个更常见的用例是,如果您有一个可迭代的序列(通常是tuples,但任何序列都可以),并且不关心它们。例如,输入list of:

      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 的给定元素中是否有四个以上的项目,而手动解包总是需要恰好四个;哪个更好主要取决于您的用例。

      【讨论】:

        猜你喜欢
        • 2021-12-02
        • 2012-12-16
        • 1970-01-01
        • 2021-07-28
        • 1970-01-01
        • 2021-08-27
        • 2019-09-18
        • 2012-02-24
        • 1970-01-01
        相关资源
        最近更新 更多