【问题标题】:An elegant way to slice a list given another list of ids to slice from给定另一个要从中切片的 id 列表来切片列表的优雅方法
【发布时间】:2016-07-10 10:17:05
【问题描述】:

我正在寻找一种优雅的方式来在 python 中对列表 l 进行切片,给定一个 ID 列表 l_ids。 例如,不要写

new_list = [l[i] for i in l_ids] 

写类似(伪代码):

new_list = l[*l_ids] 

有没有类似的方法来切片列表?

我感觉有人已经问过了,但我找不到任何参考。

编辑:可以假设所有列表项都是同一类型吗?

【问题讨论】:

标签: python slice


【解决方案1】:

你可以使用itemgetter

from operator import itemgetter

l = ['a', 'b', 'c', 'd', 'e']
l_ids = [1, 2, 3]
list(itemgetter(*l_ids)(l))

['b', 'c', 'd']

【讨论】:

    【解决方案2】:

    你可以像这样使用operator.itemgetter(*items)

    from operator import itemgetter
    
    getter = itemgetter(*lst_ids)
    new_list = list(getter(lst))
    

    另外,请注意我将l 变量重命名为lst,因为它不那么模棱两可,而且should be avoided

    您可以使用 Python 3 解包将元组隐式转换为列表,正如@JonClements 评论的那样:

    *new_list, = getter(lst)
    

    最后,从 Python 3.5 开始,还可以使用扩展解包:

    new_list = [*getter(lst)]
    

    【讨论】:

    • 如果你要提到 3.5 中的扩展解包,别忘了还有其他解包可以在 3 系列中工作(虽然它不是很漂亮)*new_lst, = getter(lst)(因为list() 将全面工作并说明其含义-无论如何我都会坚持...)
    【解决方案3】:

    我不认为导入任何东西特别优雅,或者 pythonic。

    列表推导有效,我看不出不使用它们的理由(或者没有充分的理由导入一些东西来做同样的事情):

    >>> x = [3,5,7,0,1,4,2,6]
    >>> y = ['a','b','c','d','e','f','g','h']
    >>> nList = [y[i] for i in x]
    >>> nList
    ['d', 'f', 'h', 'a', 'b', 'e', 'c', 'g']
    

    列表理解正在执行以下操作:

    indexes = [3,5,7,0,1,4,2,6]
    data = ['a','b','c','d','e','f','g','h']
    nList = []
    for index in indexes:
        nList += [data[index]]
    

    对我来说,理解看起来非常 Python 和优雅。

    【讨论】:

    • 如果作者只需要创建一次这样的列表,我认为列表理解是完全可以的,但是itemgetter()如果需要重复几次,这是一种优雅的方式。
    • @Delgan 啊,好点子。我想如果你有多个数据列表的相同 id 列表,它会更慢。
    【解决方案4】:

    我会选择 itemgetter 但你也可以 map list.__getitem__:

    l = ['a', 'b', 'c', 'd', 'e']
    l_ids = [1, 2, 3]
    
    new = list(map(l.__getitem__, l_ids))
    

    【讨论】:

    • 我不确定应该使用双前导和尾随下划线的方法,它在内部保留给 Python,不是吗?
    • 这是一个见仁见智的问题,我和许多其他人经常使用相同的逻辑来避免使用带有 map、过滤器的 lambda 调用,即 some_set.__contains__ vs lambda st: x in st 等。 .
    【解决方案5】:

    如果所有列表元素都属于同一类型,则可以使用numpy:

    from numpy import *
    new_list = array(l)[l_ids]
    

    【讨论】:

    • 如果您使用的是 numpy,那么这是一个完全不同的问题
    • numpy 是一个包,就像运算符(带有 itemgetter)一样。如果它提供了有用且简洁的解决方案,我认为没有问题。
    猜你喜欢
    • 1970-01-01
    • 2012-11-17
    • 2019-01-29
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 2017-10-22
    相关资源
    最近更新 更多