繁体   English   中英

从其他生成唯一列表

[英]Generate unique lists from other

我有以下代码可从其他列表生成唯一列表:

import itertools

def print_results_ordered_in_list(inputx):
    io = 0
    input_list = list(inputx)
    while io < (len(input_list)):
        input_list[io] = list(input_list[io])
        input_list[io] = sorted(input_list[io], key=int)
        print(input_list[io])
        io += 1

list1 = ['01', '02', '03']
list2 = ['02', '03', '04']
list3 = ['04', '05', '03']
list4 = ['05', '07', '06']
list5 = ['08', '06', '07']

listas = [list1, list2, list3, list4, list5]
all_results = set(tuple(set(i)) for i in itertools.product(*listas) if len(set(i)) == 5)

print_results_ordered_in_list(all_results)

这将生成42个不同的列表,其中包括:

['01', '03', '05', '06', '07']
['02', '03', '04', '05', '06']
['01', '03', '04', '05', '07']
['01', '03', '04', '05', '07']
['02', '03', '04', '05', '06']
['03', '04', '05', '06', '08']
['02', '03', '04', '06', '08']
['01', '02', '04', '07', '08']
['01', '04', '05', '06', '08']
    ...others lists below...

它在屏幕上打印所有生成的列表。 但是在大多数情况下,一个生成的列表与另一个生成的列表的区别仅在于1个元素(在这种情况下为数字),例如:

['01', '02', '03', '05', '06']
['01', '02', '03', '05', '07']
['01', '02', '03', '05', '08']

也就是说,仅最后一个元素已更改。

如何使所有生成的列表中的至少2个元素有所不同? 我们知道,要使一个结果与另一个结果不同,就必须仅更改1个元素,而我的代码已经这样做了,但是如何使其变为2? 例:

['01', '02', '03', '05', '06']
['01', '02', '03', '07', '08']
['02', '03', '04', '05', '07']

我们可以看到,除了是单个列表之外,从一个列表到另一个列表还至少有2个不同的元素。 那就是我想做的。

必须有更好的方法来解决此问题,但这是天真的尝试解决您的问题。 该解决方案提供了您可能没有意识到的结果。

我们建立一个元组字典,该字典与一组元组中的1)键或2)键以及彼此相关。

给定

import copy
import itertools as it
import collections as ct

import nose.tools as nt


a = ["01", "02", "03"]
b = ["02", "03", "04"]
c = ["04", "05", "03"]
d = ["05", "07", "06"]
e = ["08", "06", "07"]


# Helpers
def _is_quasi_unique(by=3, item=None, seen=None):
    """Return True if `item` differs with all `seen` items `by` some number of elements."""
    if seen is None:
        seen = set()
    return all((len(set(s) - set(item)) >= by) for s in seen)


def _has_repeats(iterable):
    """Return True if repeated elements are in `iterable`."""
    return not (len(iterable) == len(set(iterable)))


def _has_permutes(x, iterable):
    """Return True if `x` equates to any permutated item in `iterable`."""
    for item in iterable:
        if set(x) == set(item):
            return True
    return False


def _clean_subsets(subsets):
    """Yield quasi-unique, non-repeated subsets."""
    seen = set()
    for subset in subsets:
        if _has_permutes(subset, seen) or _has_repeats(subset):
            continue
        seen.add(subset)
        yield subset

# Secondary Functions
def get_cluster(subsets, seed, n=2, exclude=True):
    """Return a set of quasi-unique tuples; permit `n` similar elements.

    `seed` is a set, a starting pool of related items.

    """
    if exclude:
        set_ = seed
    else:
        set_ = copy.copy(seed)

    for subset in subsets:
        if _is_quasi_unique(n, subset, seed):
            set_.add(subset)
    return set_


def get_clean_subsets(*iterables):
    """Yield clean subsets."""
    iterables = it.product(*iterables)
    yield from _clean_subsets(iterables)


# Primary Functions
def get_clusters(subsets, n=2, exclude=True):
    """Return a dict of clusters of unique items."""
    clusters = {}
    everseen = set()
    for subset in subsets:
        if subset not in everseen:
            clusters[subset] = get_cluster(subsets, {subset}, n=n, exclude=exclude)
            everseen |= clusters[subset]
    return clusters


def find_related_items(*iterables, n=2, exclude=True):
    """Return a dict of key-cluster pairs.

    Parameters
    ----------
    iterables : tuple
        Input lists
    n : int
        Number of allowed similar elements between subsets.
    exclude: bool
        Make clusters with subsets unique within each cluster.

    """
    subsets = list(get_clean_subsets(*iterables))
    return get_clusters(subsets, n=n, exclude=exclude)

演示版

查找所有其他元组(子集)唯一的元组集

>>> find_related_items(a, b, c, d, e, n=2, exclude=False)
{('01', '02', '04', '05', '06'): 
    {('01', '02', '03', '05', '08'),
     ('01', '02', '03', '06', '08'),
     ('01', '02', '03', '07', '06'),
     ('01', '02', '03', '07', '08'),
     ('01', '02', '04', '05', '06'),
     ('01', '02', '04', '07', '08'),
     ('01', '02', '05', '07', '08'),
     ('01', '03', '04', '05', '07'),
     ('01', '03', '04', '05', '08'),
     ('01', '03', '04', '06', '08'),
     ('01', '03', '04', '07', '06'),
     ('01', '03', '04', '07', '08'),
     ('01', '03', '05', '06', '08'),
     ('01', '03', '05', '07', '06'),
     ...},
...}

查找每组(集群)中其他元组所独有的元组

>>> find_related_items(a, b, c, d, e, n=2)
{('01', '02', '03', '05', '07'): 
    {('01', '02', '03', '05', '07'),
     ('01', '02', '03', '06', '08'),
     ('01', '02', '04', '05', '08'),
     ('01', '02', '04', '07', '06'),
     ('01', '03', '04', '05', '06'),
     ('01', '03', '04', '07', '08')},
 ('01', '02', '04', '05', '06'): 
    {('01', '02', '03', '05', '08'),
     ('01', '02', '03', '07', '06'),
     ('01', '02', '04', '05', '06'),
     ('01', '02', '04', '07', '08'),
     ('01', '03', '04', '05', '07'),
     ('01', '03', '04', '06', '08')},
 ...}

细节

条款

  • 子集 :从输入项的笛卡尔积生成的元组。
  • :一组准唯一元组。
  • 准唯一的 :如果所有元素不相交,则两个元组是准唯一的,除了它们之间共享的n相似元素。

主要功能

  • find_related_items() :此函数返回干净的键-集群对。 通过使元组与排列或重复的元素分离(通过get_clean_subsets() ),可以清理子集。 通过调用get_clusters()构建集群。
  • get_clusters() :此函数通过迭代子集来生成键-集群对的字典。 所有观察到的子集的内部记录everseen集。 仅将唯一的观察值添加为字典的键。

两个结果

就以下两个方面而言,每个群集中的这些元组都是“唯一的”:

  1. 键( A ),例如A - BA - C ,( exclude=False
  2. 键和群集中的所有其他成员,例如A - BB - CC - A... ,( exclude=True

笔记

  • 集群是从_get_cluster()构建的,它依赖于初始的起始元组。 需要将此起始元组与所有其他子集进行比较,以返回一组准唯一元组。 起始元组被记录为字典的键,仅用于指示将集群中的其他元组与之进行了比较。 因此,密钥是任意的,并且不如集群重要。
  • 虽然一般模式应保持一致,但最终结果可能取决于起始元组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM