根据 Python 中的键获取排序列表的一部分

Get a slice of a sorted list according to a key in Python

是否可以根据某个键值(例如列表项的长度)对排序列表进行切片?如果是,怎么做?

例如,我得到一个这样的排序列表:

sorted_list = sorted(some_list, key=len)

现在我想得到一个切片,其中包含具有最低和相等 len 的所有项目(即 len 的所有项目: min(sorted_list, key=len) ),它应该是排序列表的头部。

你可以这样做:

min_len = len(min(some_list, key=len))
sorted_list = sorted((x for x in some_list if len(x) == min_len), key=len)

它的作用是找到列表中最小元素的长度,然后在将列表传递给sorted函数时过滤掉比该元素更长的元素。它需要额外传递数据以找到最小长度,但排序需要的时间比这长得多,因此时间成本实际上是无关紧要的。

您可以先对项目进行分组,然后获取第一个结果子迭代器的元素。

from itertools import groupby


firsts = list(next(groupby(sorted(some_list, key=len), len))[1])

例如,

>>> some_list = [[1, 2, 3], [4, 5, 6], [1], [2], [2, 3]]
>>> list(next(groupby(sorted(some_list, key=len), len))[1])
[[1], [2]]

此函数对列表进行排序,获取键(即最短长度的元素),然后构建一个仅包含等长元素的数组。

def slice_list(lst, func=len):
    # start by sorting the list
    sorted_lst = sorted(lst, key=func)

    # get the key
    key = func(sorted_lst[0])

    # get the slice
    slice = [v for v in sorted_lst if func(v) <= key]
    return slice

由于没有测试用例,这里有一个(如果我正确解释了这个问题)

test = ['abcd', 'abcde', 'efgh', '1234', 'abcdef']
print(slice_list(test, len))

产出

['abcd', 'efgh', '1234']

这更多的是出于好奇而不是实用(因为 itertools 是 真正 性能)......你可以按最小值分组并避免在单次通过中排序,就像你可以在不排序的情况下找到列表的最小值。在这里,您只需跟踪当前最小值和所有相同大小的值。如果你发现一个较小的价值报废旧的并重新开始:

some_list = ['999', '11', '22', '343', '12', '545', '99', '11', '100', '11']


def minGroup(l, f):
    it = iter(l)
    
    current = [next(it)]
    curr_min = f(current[0])

    for item in it:
        if f(item) < curr_min:
            curr_min, current = f(item), [item]
        elif f(item) == curr_min:
            current.append(item)

    return current
    

minGroup(some_list, len)
# ['11', '22', '12', '99', '11', '11']

minGroup(some_list, int)
# ['11', '11', '11']