基于子集列表的排序列表(无嵌套循环)

2024-06-23 18:56:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试根据主列表对一长串标签进行排序,并且正在努力有效地实现这一点。如下面的示例所示,我想将长列表中共享字符串公共开头的所有项组合在一起,然后以与“主列表”相同的顺序创建一个新列表。你知道吗

对于Python,我通常会尝试对数组进行矢量化和并行处理,但对于基于字符串的数组来说,这似乎效果不太好。你知道吗

下面是我使用嵌套循环的示例和解决方案:

fruits = ['apple', 'banana', 'orange']  # "master list"
labels = ['banana2', 'apple2', 'orange1', 'banana1', 'apple1', 'apple3']  # "long list"
new_list = []
for fruit in fruits:
    for label in labels:
        if fruit in label:
            new_list.append(label)

print(new_list)然后返回

['apple2', 'apple1', 'apple3', 'banana2', 'banana1', 'orange1']

没有嵌套循环可以做到这一点吗?你知道吗

另外,我希望标签也能根据字符串中的最后一个数字进行排序,例如给出结果:['apple1', 'apple2', 'apple3', 'banana1', 'banana2', 'orange1']


Tags: 字符串in示例列表new排序标签label
3条回答

另一个简单的方法:

import re

fruits = ['apple', 'banana', 'orange']  # "master list"
labels = ['banana2', 'apple2', 'orange1', 'banana1', 'apple10', 'apple3']  # "long list"

def normal_sort(text):
    return [int(c) if c.isdigit() else c for c in re.split('(\d+)', text)]

def func(x):
    x = " ".join(re.findall("[a-zA-Z]+", x))
    return x

print(sorted(sorted(labels, key=func), key=normal_sort))
# ['apple2', 'apple3', 'apple10', 'banana1', 'banana2', 'orange1']

这里有一种方法,使用^{}导出排序顺序。你知道吗

fruits = ['apple', 'banana', 'orange']
labels = ['banana2', 'apple2', 'orange1', 'banana1', 'apple1', 'apple3']

res = sorted(labels, key=lambda x: fruits.index(x[:-1]))

# ['apple2', 'apple1', 'apple3', 'banana2', 'banana1', 'orange1']

也可以使用tuple作为排序键,并结合一些正则表达式来分隔任意大小的整数。你知道吗

import re

fruits = ['apple', 'banana', 'orange']
labels = ['banana2', 'apple2', 'orange1', 'banana1', 'apple10', 'apple3']

def sorter(mystr, fruits):
    str_split = re.match(r'([a-z]+)([0-9]+)', mystr, re.I).groups()
    return (fruits.index(str_split[0]), int(str_split[1]))

res2 = sorted(labels, key=lambda x: sorter(x, fruits))

# ['apple2', 'apple3', 'apple10', 'banana1', 'banana2', 'orange1']

有几点需要改进:

  • 您不需要if fruit in label:,只需要使用if fruit == label[0:len(fruit)],因为您不需要完整的子字符串搜索,只需要开始。

  • 您可以先对labels排序,这样当您找到第一个时,您就可以添加直到检查失败,然后跳过其余的,因为这样您就可以确定它们不再匹配了。显然,排序是有成本的,但它仍然应该比每次都检查更有效。您需要一份副本,以免丢失有关它们最初是如何排序的参考资料。

相关问题 更多 >

    热门问题