python中列表的详尽组合

2024-05-16 20:31:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中有一个长长的列表,如下所示:

myList=[

('a',[1,2,3,4,5]),
('b',[6,7,8,9,10]),
('c',[1,3,5,7,9]),
('d',[2,4,6,8,10]),
('e',[4,5,6,7,8])

]

我想详尽地列举一下这些共同的价值观

^{pr2}$

四、五、六人一组也一样,直到所有的共同值都被确定(假设列表更长)

是否可以使用itertools库或集合或以上两者的组合?在

我一直在尝试编写一个函数,在我生成的每一个新列表中循环原始列表,但效果并不理想!在

以下是我所拥有的:

def findCommonElements(MyList):

    def sets(items):
        for name, tuple in items:
            yield name, set(tuple)

    def matches(sets):
       for a, b in combinations(sets, 2):
           yield ':'.join([a[0], b[0]]), a[1] & b[1]

    combinationsSet=list(matches(sets(keywordCount)))

    combinationsList=[]
    for pair,tup in combinationsSet:
        setList=list(tup)
        combinationsList.append((pair, len(setList), setList))
    combinationsList=sorted(combinationsList,key=lambda x: x[1], reverse=True) #this just sorts the list by the number of common elements

    return combinationsList

Tags: namein列表fordefsetsitemslist
3条回答

这样的怎么样?在

from itertools import combinations

myList = [
    ('a', [1, 2, 3, 4, 5]),
    ('b', [6, 7, 8, 9, 10]),
    ('c', [1, 3, 5, 7, 9]),
    ('d', [2, 4, 6, 8, 10]),
    ('e', [4, 5, 6, 7, 8]),
]


def print_commons(mList):

    letters = map(lambda l: l[0], mList)
    mdict = dict(mList)

    for i in range(2, len(letters) + 1):
        for comb in combinations(letters, i):  # generate all possible combinations
            sequence = [mdict[letter] for letter in comb]  # get the corresponding lists 
            uniques = reduce(lambda x, y: set(x).intersection(y), sequence)  # reduce the lists until only the common elements remain
            print('{} : {}'.format(comb, list(uniques)))

print_commons(myList)

('a', 'b') : []
('a', 'c') : [1, 3, 5]
('a', 'd') : [2, 4]
('a', 'e') : [4, 5]
('b', 'c') : [9, 7]
('b', 'd') : [8, 10, 6]
('b', 'e') : [8, 6, 7]
('c', 'd') : []
('c', 'e') : [5, 7]
('d', 'e') : [8, 4, 6]
('a', 'b', 'c') : []
('a', 'b', 'd') : []
('a', 'b', 'e') : []
('a', 'c', 'd') : []
('a', 'c', 'e') : [5]
('a', 'd', 'e') : [4]
('b', 'c', 'd') : []
('b', 'c', 'e') : [7]
('b', 'd', 'e') : [8, 6]
('c', 'd', 'e') : []
('a', 'b', 'c', 'd') : []
('a', 'b', 'c', 'e') : []
('a', 'b', 'd', 'e') : []
('a', 'c', 'd', 'e') : []
('b', 'c', 'd', 'e') : []
('a', 'b', 'c', 'd', 'e') : []

我想你可以试着用itertools.combinationsitertools.chain

这不是一个很好的例子,但应该行得通。 我将在这里使用itertools和生成器:

lengthes = xrange(2, len(myList)+1)
combinations_list = (itertools.combinations(myList, i) for i in lengthes)
combinations = itertools.chain.from_iterable(combinations_list)
def find_intersection(lists):
    res = set(lists[0])
    for data in lists:
        res &= set(data)
    return res
result = [(':'.join(i), list(find_intersection(v))) for i, v in (zip(*x) for x in combinations)]

或者只是itertools.combinations

^{pr2}$

下面是一个使用我刚刚创建的字典的解决方案:

def iter_recursive_common_elements(lists, max_depth=None):
    data = [{k:set(v) for k,v in lists.iteritems()}] # guarantee unique
    depth = 0

    def get_common_elements(lists, base):
        d = {}
        for k, v in lists.iteritems():
            merged = k.split(':')
            potential = set(base).difference(merged)
            for target in potential:
                d[':'.join(sorted(merged+[target]))] = v.intersection(base[target])
        return d if d else None

    while True:
        ret = get_common_elements(data[depth], data[0])
        if not ret:
            break
        data.append(ret)
        depth += 1
        yield data[depth]
        if max_depth and depth > max_depth:
            break

使用它非常简单:

^{pr2}$

还可以清理输出以匹配您想要的更多内容:

for x in iter_recursive_common_elements(lists):
    for k, v in sorted(x.items()):
        if v:
            print '(%s) : %s' % (k.replace(':', ', '), list(v))

>>> 
(a, c) : [1, 3, 5]
(a, d) : [2, 4]
(a, e) : [4, 5]
(b, c) : [9, 7]
(b, d) : [8, 10, 6]
(b, e) : [8, 6, 7]
(c, e) : [5, 7]
(d, e) : [8, 4, 6]
(a, c, e) : [5]
(a, d, e) : [4]
(b, c, e) : [7]
(b, d, e) : [8, 6]

相关问题 更多 >