如果不满足条件,则删除列表列表中的列表
Removing a list in a list of lists if a condition not satisfied
我有一个列表列表。如果列表中的值与先前列表的交集长度超过一个,我想删除列表。
例如
A=[(1,2,3,4), (2,3,5,6),(1,7,8,9),(2,4,6,8)]
我们需要保留第一个列表,因为没有之前的列表。我们删除 (2,3,5,6)
,因为它与先前列表的交集是 (2,3)
,它的长度是 2
。我们保留 (1,7,8,9)
并同样删除 (2,4,6,8)
。
最后我们的列表应该变成 B=[(1,2,3,4), (1,7,8,9)]
通常情况下,这段代码应该可以满足您的需求
A=[(1,2,3,4), (2,3,5,6),(1,7,8,9),(2,4,6,8)]
B = []
precedent = []
for list_ in A:
intersection = 0
for num in list_:
if num in precedent:
intersection += 1
if intersection < 1:
B.append(list_)
precedent = list_
我认为这是您可以尝试的一种方法。
def intersection_length(lst1, lst2):
intersection_list = [value for value in lst1 if value in lst2]
return len(intersection_list)
def filter_lists(lists):
filtered_lists = []
filtered_lists.append(lists[0])
del lists[0]
for list_item in lists:
is_ok = True
for prev_list in filtered_lists:
if intersection_length(list_item, prev_list) > 1:
is_ok = False
continue
if is_ok:
filtered_lists.append(list_item)
return filtered_lists
def main():
filtered = filter_lists(
[(1, 2, 3, 4), (2, 3, 5, 6), (1, 7, 8, 9), (2, 4, 6, 8)]
)
print(filtered)
if __name__ == "__main__":
main()
这是一个可能的解决方案:
A=[(1,2,3,4),(2,3,5,6),(1,7,8,9),(2,4,6,8)]
B=[]
# iterate over sublists a of the list A
for a in A:
# define and reset the intersections counter
intersections=0
# iterate of sublists b of B
for b in B:
# reset the intersections counter
intersections=0
# iterate over the numbers num of sublist a
for num in a:
# perform checks
if num in b:
intersections+=1
if intersections>1:
break
# break the iteration over sublists b if check fulfilled
if intersections>1:
break
# Append a to the subset B only if intersection were not > 1
if intersections>1:
continue
B.append(a)
# repeat
#B now contains the result...
print(B)
这里是一个直接的实现:
A = [(1,2,3,4), (2,3,5,6), (1,7,8,9), (2,4,6,8)]
B = []
intersect = 0
for a in A:
for b in B:
intersect = 0
for num in b:
if num in a:
intersect += 1
if intersect > 1:
break
if intersect < 2:
B.append(a)
给出:
B = [(1, 2, 3, 4), (1, 7, 8, 9)]
一个可能更有效的解决方案,以防您拥有(并保留)更多但仍然很短的元组。这将检查列表中的数字对。如果 none 对出现在已保留的元组中,则保留当前元组 a
。
from itertools import combinations
A = [(1,2,3,4), (2,3,5,6), (1,7,8,9), (2,4,6,8)]
B = []
B_pairs = set()
for a in A:
pairs = set(map(frozenset, combinations(a, 2)))
if not B_pairs & pairs:
B.append(a)
B_pairs |= pairs
print(B)
Ouss 解决方案的一些基准测试,因为他们提出了这个问题:
With 5000 tuples, 2553 of which are kept:
23 ms Kelly
2853 ms Ouss
With 5000 tuples, 2540 of which are kept:
21 ms Kelly
2776 ms Ouss
With 5000 tuples, 2558 of which are kept:
20 ms Kelly
2685 ms Ouss
基准代码(Try it online!):
from itertools import combinations
def Kelly(A):
B = []
B_pairs = set()
for a in A:
pairs = set(map(frozenset, combinations(a, 2)))
if not B_pairs & pairs:
B.append(a)
B_pairs |= pairs
return B
def Ouss(A):
B=[]
# iterate over sublists a of the list A
for a in A:
# define and reset the intersections counter
intersections=0
# iterate of sublists b of B
for b in B:
# reset the intersections counter
intersections=0
# iterate over the numbers num of sublist a
for num in a:
# perform checks
if num in b:
intersections+=1
if intersections>1:
break
# break the iteration over sublists b if check fulfilled
if intersections>1:
break
# Append a to the subset B only if intersection were not > 1
if intersections>1:
continue
B.append(a)
# repeat
#B now contains the result...
return B
from timeit import timeit
from random import sample
A = [tuple(sample(range(100), 4)) for _ in range(500)]
print(Kelly(A) == Ouss(A), len(Kelly(A)))
for _ in range(3):
A = [tuple(sample(range(400), 4)) for _ in range(5000)]
print(f'With {len(A)} tuples, {len(Kelly(A))} of which are kept:')
for func in Kelly, Ouss:
time = timeit(lambda: func(A), number=1)
print('%4d ms ' % (time * 1e3), func.__name__)
print()
我有一个列表列表。如果列表中的值与先前列表的交集长度超过一个,我想删除列表。
例如
A=[(1,2,3,4), (2,3,5,6),(1,7,8,9),(2,4,6,8)]
我们需要保留第一个列表,因为没有之前的列表。我们删除 (2,3,5,6)
,因为它与先前列表的交集是 (2,3)
,它的长度是 2
。我们保留 (1,7,8,9)
并同样删除 (2,4,6,8)
。
最后我们的列表应该变成 B=[(1,2,3,4), (1,7,8,9)]
通常情况下,这段代码应该可以满足您的需求
A=[(1,2,3,4), (2,3,5,6),(1,7,8,9),(2,4,6,8)]
B = []
precedent = []
for list_ in A:
intersection = 0
for num in list_:
if num in precedent:
intersection += 1
if intersection < 1:
B.append(list_)
precedent = list_
我认为这是您可以尝试的一种方法。
def intersection_length(lst1, lst2):
intersection_list = [value for value in lst1 if value in lst2]
return len(intersection_list)
def filter_lists(lists):
filtered_lists = []
filtered_lists.append(lists[0])
del lists[0]
for list_item in lists:
is_ok = True
for prev_list in filtered_lists:
if intersection_length(list_item, prev_list) > 1:
is_ok = False
continue
if is_ok:
filtered_lists.append(list_item)
return filtered_lists
def main():
filtered = filter_lists(
[(1, 2, 3, 4), (2, 3, 5, 6), (1, 7, 8, 9), (2, 4, 6, 8)]
)
print(filtered)
if __name__ == "__main__":
main()
这是一个可能的解决方案:
A=[(1,2,3,4),(2,3,5,6),(1,7,8,9),(2,4,6,8)]
B=[]
# iterate over sublists a of the list A
for a in A:
# define and reset the intersections counter
intersections=0
# iterate of sublists b of B
for b in B:
# reset the intersections counter
intersections=0
# iterate over the numbers num of sublist a
for num in a:
# perform checks
if num in b:
intersections+=1
if intersections>1:
break
# break the iteration over sublists b if check fulfilled
if intersections>1:
break
# Append a to the subset B only if intersection were not > 1
if intersections>1:
continue
B.append(a)
# repeat
#B now contains the result...
print(B)
这里是一个直接的实现:
A = [(1,2,3,4), (2,3,5,6), (1,7,8,9), (2,4,6,8)]
B = []
intersect = 0
for a in A:
for b in B:
intersect = 0
for num in b:
if num in a:
intersect += 1
if intersect > 1:
break
if intersect < 2:
B.append(a)
给出:
B = [(1, 2, 3, 4), (1, 7, 8, 9)]
一个可能更有效的解决方案,以防您拥有(并保留)更多但仍然很短的元组。这将检查列表中的数字对。如果 none 对出现在已保留的元组中,则保留当前元组 a
。
from itertools import combinations
A = [(1,2,3,4), (2,3,5,6), (1,7,8,9), (2,4,6,8)]
B = []
B_pairs = set()
for a in A:
pairs = set(map(frozenset, combinations(a, 2)))
if not B_pairs & pairs:
B.append(a)
B_pairs |= pairs
print(B)
Ouss 解决方案的一些基准测试,因为他们提出了这个问题:
With 5000 tuples, 2553 of which are kept:
23 ms Kelly
2853 ms Ouss
With 5000 tuples, 2540 of which are kept:
21 ms Kelly
2776 ms Ouss
With 5000 tuples, 2558 of which are kept:
20 ms Kelly
2685 ms Ouss
基准代码(Try it online!):
from itertools import combinations
def Kelly(A):
B = []
B_pairs = set()
for a in A:
pairs = set(map(frozenset, combinations(a, 2)))
if not B_pairs & pairs:
B.append(a)
B_pairs |= pairs
return B
def Ouss(A):
B=[]
# iterate over sublists a of the list A
for a in A:
# define and reset the intersections counter
intersections=0
# iterate of sublists b of B
for b in B:
# reset the intersections counter
intersections=0
# iterate over the numbers num of sublist a
for num in a:
# perform checks
if num in b:
intersections+=1
if intersections>1:
break
# break the iteration over sublists b if check fulfilled
if intersections>1:
break
# Append a to the subset B only if intersection were not > 1
if intersections>1:
continue
B.append(a)
# repeat
#B now contains the result...
return B
from timeit import timeit
from random import sample
A = [tuple(sample(range(100), 4)) for _ in range(500)]
print(Kelly(A) == Ouss(A), len(Kelly(A)))
for _ in range(3):
A = [tuple(sample(range(400), 4)) for _ in range(5000)]
print(f'With {len(A)} tuples, {len(Kelly(A))} of which are kept:')
for func in Kelly, Ouss:
time = timeit(lambda: func(A), number=1)
print('%4d ms ' % (time * 1e3), func.__name__)
print()