从python列表中删除不必要的项目

时间:2019-03-09 18:38:27

标签: python list combinations

我有一个8个唯一的元组的列表,每个元组的大小为2。从那里,我找到了大小为4的所有可能的组合。现在,我有了一个列表的列表,并且在每个子列表中我都有4个元组。像-

<body onload="applyButton()"> <h1>Vanilla JS ToDo List - No Jquery, No Bootstrap</h1> <div class='container'> <div id='main-grid'> <div class="container2"> <div id='inputIdForGrid'> <input type='text' placeholder="Enter List Items Here" id='newNote'> </div> <div> <a href='#' id="addItem">Hi</a> </div> </div> <ul id='list-body'> <li><span>run all around town. walk all around town. drive all around town</span></li> <li><span>Buy Apples</span></li> <li><span>Hit Gym and Lift Bro</span></li> <li><span>Stretch</span></li> </ul> </div> </div> </body>

可能在主列表中-

span

这些实际上是2D平面中点的坐标,我将8个点分成两组,每组4个。因此,如果我有4分的列表,则意味着我也已经有其他4分。因此,对于4分的每种组合,我都尝试从列表中删除其他4分。

以下作品-

[[(1, 2), (4, 5), (223, 456), (111, 345)], [...], ...]

我尝试仅使用[(1, 2), (4, 5), (223, 456), (111, 345), (123, 4), (23, 89), (999, 888), (895, 569)],但它对列表项进行了重新排序,因此无法直接删除它们。我在注释行中尝试过。我所做的就是找到8中剩余的4点,然后如果4与组合列表中任何项的集合差的长度为零,则意味着在一起,这4点的集合都匹配唯一8,因此我删除了该特定项目。

有没有一种方法可以直接在一行或两行中实现这一点而没有循环?

谢谢。

1 个答案:

答案 0 :(得分:1)

更好的解决方案是首先避免生成不需要的组合。

这实际上很容易,因为组合是按顺序生成的。我们只需要取它们的前半部分。在8(8 * 7 * 6 * 5 /(4 * 3 * 2))中有4个点的70个组合,因此我们只保留前35个。

一个演示,使用1到8的数字代替元组以提高可读性:

from itertools import combinations, islice

l = [1, 2, 3, 4, 5, 6, 7, 8]

nb_combinations = 70
print(list(islice(combinations(l, 4), nb_combinations//2)))

输出:

[(1, 2, 3, 4), (1, 2, 3, 5), (1, 2, 3, 6), (1, 2, 3, 7), (1, 2, 3, 8), 
(1, 2, 4, 5), (1, 2, 4, 6), (1, 2, 4, 7), (1, 2, 4, 8), (1, 2, 5, 6), 
(1, 2, 5, 7), (1, 2, 5, 8), (1, 2, 6, 7), (1, 2, 6, 8), (1, 2, 7, 8),
(1, 3, 4, 5), (1, 3, 4, 6), (1, 3, 4, 7), (1, 3, 4, 8), (1, 3, 5, 6),
(1, 3, 5, 7), (1, 3, 5, 8), (1, 3, 6, 7), (1, 3, 6, 8), (1, 3, 7, 8),
(1, 4, 5, 6), (1, 4, 5, 7), (1, 4, 5, 8), (1, 4, 6, 7), (1, 4, 6, 8),
(1, 4, 7, 8), (1, 5, 6, 7), (1, 5, 6, 8), (1, 5, 7, 8), (1, 6, 7, 8)]

您可以看到这35个组合中的所有组合都包含第一个值1,因此我们可以确定它们中的任何一个都不是该组合中另一个组合的补充。 

因此,您的函数可以编写为:

from itertools import combinations, islice

def generate_4points(points):
    # we only keep the first 35 combinations out of 70
    return list(islice(combinations(points, 4), 35))