在列表中查找特定字符串的索引

时间:2019-02-16 14:22:21

标签: python regex

我有一个频道列表:

channels = ['1LT1', '1LT2', '1LT3', '1LT4', '1LT5', '2LA1', '2LA2', '2LA3', '3LH1', '3LH5', '4LT1', '4LT2', '4LT3', '5LH1', '5LH2', '4LT10']

我需要写一个算法以只留下远端通道。这意味着对于每种类型的通道(“ 1LT”,“ 2LA”,“ 3LH”,“ 4LT”等),我只需要最后编号最高的通道即可。  最好的方法是返回这些通道的索引。例如,对于上述列表,结果应为:

distal_i = [4, 7, 9, 14, 15]

我认为我可以通过正则表达式拆分来实现:

labels = [re.findall('(\d+)(\w+?)(\d+)', channel) for channel in channels]

它给了我

[('1', 'LT', '1'),
 ('1', 'LT', '2'),
 ('1', 'LT', '3'),
 ('1', 'LT', '4'),
 ('1', 'LT', '5'),
 ('2', 'LA', '1'),
 ('2', 'LA', '2'),
 ('2', 'LA', '3'),
 ('3', 'LH', '1'),
 ('3', 'LH', '5'),
 ('4', 'LT', '1'),
 ('4', 'LT', '2'),
 ('4', 'LT', '3'),
 ('5', 'LH', '1'),
 ('5', 'LH', '2'),
 ('4', 'LT', '10')]

但是后来我真的被困住了。 有人可以给我一些技巧来创建好的算法吗?

我真的很感谢任何想法!

2 个答案:

答案 0 :(得分:0)

根据您的尝试,构建一个字典,其中包含每个远端和索引的最大值,然后映射索引。

import re

channels = ['1LT1', '1LT2', '1LT3', '1LT4', '1LT5', '2LA1', '2LA2', '2LA3', '3LH1', '3LH5', '4LT1', '4LT2', '4LT3', '5LH1', '5LH2', '4LT10']

highest = {}
for (i, c) in enumerate(channels):
    [[distal, num]] = re.findall('(\d+\w{2})(\d+)', c)
    if distal not in channels:
        highest[distal] = { 'idx': i, 'num': num }
    else:
        if highest[distal]['num'] < num:
            highest[distal] = { 'idx': i, 'num': num }

distal_i = [h['idx'] for _, h in highest.items()]
print(distal_i)
# [4, 7, 9, 14, 15]

答案 1 :(得分:0)

您可以使用元组的字典来跟踪每种通道类型的最大数量和出现的索引。 dict键按其第一次插入的顺序排列,但是由于您希望最终顺序遵循出现最大数字的位置,因此,应先删除现有键,以便在您每次插入新条目时将其插入正确的位置找到一个新的频道最大数量:

import re
d = {}
for i, channel in enumerate(channels):
    type, n = re.findall('\d+[A-Z]*', channel)
    n = int(n)
    if type in d:
        if n > d[type][0]:
            del d[type]
        else:
            continue
    d[type] = n, i
print([i for _, i in d.values()])

这将输出:

[4, 7, 9, 14, 15]

请注意,仅自python 3.7起就保证可以对字典进行排序。如果您使用的是早期版本,则可以将d初始化为collections.OrderedDict

from collections import OrderedDict
d = OrderedDict()