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

标签 python list combinations

我有一个包含 8 个唯一元组的列表,每个元组的大小为 2。从那里我找到了大小为 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)]

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

以下作品 -

def generate_all_points(points, size):
    from itertools import combinations

    all_combinations = combinations(points, size)
    return (list(all_combinations))    

def generate_4points(points):

    all_4points = generate_all_points(points, 4)
    print (len(all_4points))
    print ("ALL POINTS -\t", points)
    for point_set in all_4points:

        to_remove = list(set(points).difference(set(point_set)))
        for item in all_4points:
            if (len(set(to_remove).difference(item)) == 0):
                all_4points.remove(item)

        print ("Main -\t", point_set, "\nTo Remove -\t", to_remove)
        #all_4points.remove(list(set(points).difference(set(point_set))))
    print (len(all_4points))

我尝试仅使用 set.difference 但它对列表项重新排序,因此我无法直接删除它们。我在评论行中尝试过。我所做的是从 8 个点中找到剩余的 4 个点,然后如果 4 个点和组合列表中的任何项目的集合差的长度为零,那么这意味着两个 4 点集一起匹配唯一的8,因此我删除了该特定项目。

有没有一种方法可以直接用一两行来实现这一点,而无需循环等?

提前致谢。

最佳答案

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

这实际上相当简单,因为组合是按顺序生成的。我们只需要拿走其中的前半部分即可。 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))

关于python - 从 python 列表中删除不必要的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55080740/

相关文章:

python - ProcessPoolExecutor 和 ThreadPoolExecutor 有什么区别?

python - 使用标准输出同时写入多行

python - 尽管数据库/模型中存在数据,FastAPI 并未选择嵌套模式

python - 通过python在csv文件的两列数据之间创建不同的组合/模式

javascript - 无重复的笛卡尔积

python - 在 PyCharm 上使用 Python 3.4 时出现无效的 Python SDK 错误

python - 读取值并将它们写为逗号分隔值 python

python - 递归和随机分组列表

python为列表中的每个元素添加一个id

matlab - 总和的组合