Python:基于另一个列表中的子字符串的一个列表中的子集元素,每个子字符串只保留一个元素

时间:2017-09-19 14:19:36

标签: python subset

我有两个清单:

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函数是否能以某种方式纳入这个问题?任何建议将不胜感激!

3 个答案:

答案 0 :(得分: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']

答案 1 :(得分:0)

您可以使用以下功能:

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)

答案 2 :(得分:0)

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

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']