【问题标题】:Python: subset elements in one list based on substring in another list, retain only one element per substringPython:一个列表中的子集元素基于另一个列表中的子字符串,每个子字符串仅保留一个元素
【发布时间】:2017-09-19 14:19:36
【问题描述】:

我有两个列表:

list1 = ['abc-21-6/7', 'abc-56-9/10', 'def-89-7/3', 'hij-2-4/9', 'hij-75-1/7']

list2 = ['abc', 'hij']

我想对 list1 进行子集化,这样:1)只保留那些子字符串与 list2 中的元素匹配的元素,以及 2)对于满足第一个要求的重复元素,我只想随机保留一个重复项。对于这个具体的例子,我想产生如下结果:

['abc-21-6/7', 'hij-75-1/7']

我已经编写了代码来满足我的第一个要求:

[ele for ele in list1 for x in list2 if x in ele]

根据我的具体示例,返回以下内容:

['abc-21-6/7', 'abc-56-9/10', 'hij-2-4/9', 'hij-75-1/7']

但我被困在第二步 - 在重复子字符串的情况下如何随机保留一个元素。我想知道 random.choice 函数是否可以以某种方式合并到这个问题中?任何建议将不胜感激!

【问题讨论】:

  • list2 事物总是在 list1 事物的开头吗?如果是这样,您可以对这两个列表进行排序并获得nlogn 解决方案。否则你就是二次方。
  • 是的,他们总是在这个特定问题的开始。感谢您的意见!

标签: python subset


【解决方案1】:

你可以使用itertools.groupby:

import itertools
import random
list1 = ['abc-21-6/7', 'abc-56-9/10', 'def-89-7/3', 'hij-2-4/9', 'hij-75-1/7']

list2 = ['abc', 'hij']
new_list1 = [i for i in list1 if any(b in i for b in list2)]
new_data = [list(b) for a, b in itertools.groupby(new_list1, key=lambda x: x.split("-")[0])]
final_data = [random.choice(i) for i in new_data]

输出:

['abc-56-9/10', 'hij-75-1/7']

【讨论】:

  • @nrcombs 很高兴为您提供帮助!
【解决方案2】:

您可以使用以下功能:

def find(list1, findable):
    for element in list1:
        if findable in element:
            return element

现在我们可以使用列表推导:

[find(list1, ele) for ele in list2 if find(list1, ele) is not None]

这可以在没有列表理解的情况下加速:

result = []
for ele in list2:
    found = find(list1, ele)
    if found is not None:
        result.append(found)

【讨论】:

    【解决方案3】:

    您可以使用字典而不是列表,然后将值转换为列表。

    list1 = ['abc-21-6/7', 'abc-56-9/10', 'def-89-7/3', 'hij-2-4/9', 'hij-75-1/7']
    list2 = ['abc', 'hij']
    
    final_list = {pref:ele for pref in list2 for ele in list1 if pref in ele}
    final_list = list(final_list.values())
    

    这将输出:

    >>>final_list
    ['abc-56-9/10', 'hij-75-1/7']
    

    【讨论】:

    • 感谢何塞·加西亚!
    • 没问题!我认为这更实用一些,因为您不必导入外部模块或定义任何函数
    猜你喜欢
    • 2019-08-03
    • 2014-03-10
    • 2022-11-14
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2020-06-21
    相关资源
    最近更新 更多