根据条件合并两个列表

时间:2014-02-10 21:25:42

标签: python list

我正在尝试根据索引的位置合并两个列表,因此需要对接近交叉点进行排序。

在这种情况下,套装不起作用。我想要做的是匹配每个列表中的索引,然后如果元素比其他列表中的元素少一个,那么我才收集它。

一个例子可以更好地解释我的情景。

示例输入:

print merge_list([[0, 1, 3], [1, 2], [4, 1, 3, 5]], 
                 [[0, 2, 6], [1, 4], [2, 2], [4, 1, 6]])

示例输出:

[[0,2],[4,6]]

所以在list1中的位置0我们有1,3,而在list2中我们有2,6。因为1是一个小于2,所以我们收集它并继续前进,现在3小于6但是它不是一个比不是5,所以我们忽略了。接下来我们有[1,2] [1,4],所以索引/位置1,但是2不小于4,所以我们忽略它。接下来我们在list2中有[2,2],索引2与第一个列表中的任何索引都不匹配,因此没有比较。最后我们进行了[4,1,3,5] [4,1,6]比较。两个索引匹配并且列表1中只有5个比列表2少一个所以我们收集六个因此我们收集[4,6]意义索引4并匹配等。

我试图让它发挥作用,但我似乎并没有让它发挥作用。

到目前为止,这是我的代码。

def merge_list(my_list1, my_list2):
merged_list = []
bigger_list = []
smaller_list = []

temp_outer_index = 0
temp_inner_index = 0  

if(len(my_list1) > len(my_list2)):
    bigger_list = my_list1
    smaller_list = my_list2
elif(len(my_list2) > len(my_list1)):
    bigger_list = my_list2
    smaller_list = my_list1
else:
    bigger_list = my_list1
    smaller_list = my_list2

for i, sublist in enumerate(bigger_list):             
    for index1 , val in enumerate(sublist):           
            for k, sublist2 in enumerate(smaller_list):
                for index2, val2 in enumerate(sublist2):                       
                    temp_outer_index = index1 + 1          
                    temp_inner_index = index2 + 1
                    if(temp_inner_index < len(sublist2) and temp_outer_index < len(sublist)):
                        # print "temp_outer:%s , temp_inner:%s, sublist[temp_outer]:%s, sublist2[temp_inner_index]:%s" % (temp_outer_index, temp_inner_index, sublist[temp_outer_index], sublist2[temp_inner_index]) 
                        if(sublist2[temp_inner_index] < sublist[temp_outer_index]):
                            merged_list.append(sublist[temp_outer_index])
                            break


return  merged_list

3 个答案:

答案 0 :(得分:2)

不知道你在做什么,但这应该有用。

首先,将列表列表转换为索引到该列表中包含的数字集的映射:

def convert_list(l):
    return dict((sublist[0], set(sublist[1:])) for sublist in l)

这将使列表更容易使用:

>>> convert_list([[0, 1, 3], [1, 2], [4, 1, 3, 5]])
{0: set([1, 3]), 1: set([2]), 4: set([1, 3, 5])}
>>> convert_list([[0, 2, 6], [1, 4], [2, 2], [4, 1, 6]])
{0: set([2, 6]), 1: set([4]), 2: set([2]), 4: set([1, 6])}

现在merge_lists函数可以写成:

def merge_lists(l1, l2):
    result = []
    d1 = convert_list(l1)
    d2 = convert_list(l2)
    for index, l2_nums in d2.items():
        if index not in d1:
            #no matching index
            continue
        l1_nums = d1[index]
        sub_nums = [l2_num for l2_num in l2_nums if l2_num - 1 in l1_nums]
        if sub_nums:
            result.append([index] + sorted(list(sub_nums)))
    return result

适用于您的测试用例:

>>> print merge_lists([[0, 1, 3], [1, 2], [4, 1, 3, 5]], 
                      [[0, 2, 6], [1, 4], [2, 2], [4, 1, 6]]) 
[[0, 2], [4, 6]]

答案 1 :(得分:1)

我相信这可以做你想做的事情:

import itertools

def to_dict(lst):
    dct = {sub[0]: sub[1:] for sub in lst}
    return dct

def merge_dicts(a, b):
    result = []
    overlapping_keys = set.intersection(set(a.keys()), set(b.keys()))
    for key in overlapping_keys:
        temp = [key] # initialize sublist with index
        for i, j in itertools.product(a[key], b[key]):
            if i == j - 1:
                temp.append(j)
        if len(temp) > 1: # if the sublist has anything besides the index
            result.append(temp)
    return result

dict1 = to_dict([[0, 1, 3], [1, 2], [4, 1, 3, 5]])
dict2 = to_dict([[0, 2, 6], [1, 4], [2, 2], [4, 1, 6]])

result = merge_dicts(dict1, dict2)
print(result)

结果:

[[0, 2], [4, 6]]

首先,我们将您的列表转换为dicts,因为它们更容易使用(这会将键与其他值分开)。然后,我们查找两个dicts中存在的键(在本例中,这是0,1,4),并查看每个键的两个dicts之间的所有值对(在示例中,1,2; 1, 6; 3,2; 3,6; 2,4; 1,1; 1,6; 3,1; 3,6; 5,1; 5,6)。只要一对中的第一个元素比第二个元素少一个,我们就会将第二个元素添加到temp列表中。如果temp列表最终包含除密钥之外的任何内容(即长度超过1),我们会将其添加到result列表中,最终返回该列表。

(我突然意识到这有很糟糕的表现特征 - 子列表的长度是二次的 - 所以你可能想要使用Claudiu的答案,如果你的子列表会很长。如果他们将会是但是,我认为初始化一个集合的成本足够大,以至于我的解决方案可能会更快。)

答案 2 :(得分:1)

def merge_list(a, b):
    d = dict((val[0], set(val[1:])) for val in a)
    result = []
    for val in b:
        k = val[0]
        if k in d:
            match = [x for x in val[1:] if x - 1 in d[k]]
            if match:
                result.append([k] + match)
    return result

与其他答案类似,这将首先将其中一个列表转换为字典,每个内部列表的第一个元素作为键,列表的其余部分作为值。然后我们浏览另一个列表,如果第一个元素作为字典中的键存在,我们使用列表推导找到符合您标准的所有值,如果有,请在result列表中添加一个条目最后归还。