【问题标题】:How to filter a certain type of python list如何过滤某种类型的python列表
【发布时间】:2021-04-08 12:43:35
【问题描述】:

我有一个字符串列表。每个字符串在格式中具有相同的长度/字符数 xyzw01.extxyzv02.ext

例如

list 1: ['ABCJ01.ext','CDEJ02.ext','ADEJ01.ext','CDEJ01.ext','ABCJ02.ext','CDEJ03.ext']
list 2: ['ABCJ01.ext','ADEJ01.ext','CDEJ01.ext','RPNJ01.ext','PLEJ01.ext']

我想从这些列表中构建新列表,其中仅包含数字最高的字符串。 所以从列表 1 中我想得到

['ADEJ01.ext','ABCJ02.ext','CDEJ03.ext']

而对于列表 2,我想获得相同的列表,因为所有数字都是 01。

有没有“简单”的方法来实现这一点?

【问题讨论】:

标签: python-3.x


【解决方案1】:

您可以使用defaultdictmax

from collections import defaultdict

def fun(lst):
    res = defaultdict(list)
    for x in lst:
        res[x[:4]].append(x)
    return [max(res[x], key=lambda x: x[4:6]) for x in res]


lst = ['ABCJ01.ext','CDEJ02.ext','ADEJ01.ext','CDEJ01.ext','ABCJ02.ext','CDEJ03.ext']
lst2 = ['ABCJ01.ext','ADEJ01.ext','CDEJ01.ext','RPNJ01.ext','PLEJ01.ext']

print(fun(lst))
print(fun(lst2))

输出:

['ABCJ02.ext', 'CDEJ03.ext', 'ADEJ01.ext']
['ABCJ01.ext', 'ADEJ01.ext', 'CDEJ01.ext', 'RPNJ01.ext', 'PLEJ01.ext']

【讨论】:

    【解决方案2】:

    最简单的方法可能是使用中间数据结构,例如dict - 根据名称的第一部分将列表项排序到存储桶中,然后为每个存储桶取最大数量。我们可以只使用内置的max() 而不使用键,因为给定的字典排序可以找到最大的。如果这还不够,您可以使用更多正则表达式从项目中取出数字并将其用作键。

    import re
    
    def filter_list(lst):
        prefixes = {}
        for item in lst:
            # use regex to isolate the non-numeric characters at the start of the string
            prefix = re.match(r'^([^0-9]*)', item).group(1)
            # make a bucket based on each prefix, and put the item in it
            prefixes.setdefault(prefix, [])
            prefixes[prefix].append(item)
        # make a list comprehension taking the maximum item from each bucket
        return [max(value) for value in prefixes.values()]
    
    >>> a = ['ABCJ01.ext','CDEJ02.ext','ADEJ01.ext','CDEJ01.ext','ABCJ02.ext','CDEJ03.ext']
    >>> b = ['ABCJ01.ext','ADEJ01.ext','CDEJ01.ext','RPNJ01.ext','PLEJ01.ext']
    >>> filter_list(a)
    ['ABCJ02.ext', 'CDEJ03.ext', 'ADEJ01.ext']
    >>> filter_list(b)
    ['ABCJ01.ext', 'ADEJ01.ext', 'CDEJ01.ext', 'RPNJ01.ext', 'PLEJ01.ext']
    

    在 python 3.7+ 中,这应该从 每个前缀的第一次出现 保留列表的顺序(即,CDEJ03.ext 将在输出中位于 ADEJ01.ext 之前,因为 CDEJ02.ext 在它之前输入)。
    要以与原始列表完全相同的顺序获得输出,行为,您需要明确地重新分配键,而不是使用 .setdefault(),也许使用像 prefixes[prefix] = prefixes[prefix] if prefix in prefixes else [] 这样的模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-26
      • 2011-11-04
      • 2019-09-27
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多