[英]Merge two lists based on condition
我試圖基於索引的位置合並兩個列表,所以有點接近相交。
設置在這種情況下不起作用。 我想做的是每個列表中的匹配索引,然后如果該元素比其他列表中的元素小一個,則只有我收集它。
一個例子將更好地解釋我的情況。
輸入樣例:
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,但不小於1,即不是5,所以我們忽略了這一點。 接下來,我們有[1,2] [1,4],因此索引/位置1均不小於4,所以2不小於1,因此我們忽略了這一點。 接下來,我們在list2中具有[2,2],兩個索引2與第一個列表中的任何索引都不匹配,因此沒有比較。 最后,我們有[4,1,3,5] [4,1,6]比較。 索引匹配和列表1中只有5個比列表2少一個,因此我們收集了6個,因此我們收集了[4,6],意味着索引4和match等。
我試圖使它起作用,但是我似乎沒有使其起作用。
到目前為止,這是我的代碼。
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
不知道您在做什么,但這應該可以。
首先,將列表列表轉換為索引到該列表中包含的一組數字的映射:
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]]
我相信這可以滿足您的要求:
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]]
首先,我們將您的列表轉換為字典,因為它們更易於使用(這將鍵與其他值分開)。 然后,我們尋找兩個字典中都存在的鍵(在本例中為0、1、4),並針對每個鍵查看兩個字典之間的所有值對(在本例中為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的答案。但是,如果子列表會很短, ,我認為初始化集合的成本足以使我的解決方案更快。)
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
列表中添加一個條目,該條目將在列表中返回。結束。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.