最多4个列表的维恩图 - 输出交集和唯一集合
在我的工作中,我经常使用维恩图,目前我主要依赖一个网页工具叫做 "Venny"。这个工具有个不错的功能,可以导出不同交集的元素,也就是那些只属于特定交集的元素。而且,它可以处理最多4个列表的图示。
不过,问题是,当列表很大(超过4000个元素)并且有超过3个集合时,操作起来就很麻烦(需要复制、粘贴、保存……)。所以,我决定自己生成这些列表,只用这个工具来绘制图形。
这段长长的介绍其实是为了引出重点。假设我有3个或4个列表,它们之间有一些相同的元素,我该如何在Python中处理这些列表,以得到不同的集合(比如,独特的元素、4个列表共有的元素、只有第一个和第二个列表共有的元素等等),就像维恩图中显示的那样(3个列表的图示例,4个列表的图示例)?对于3个列表来说,这看起来不太难,但对于4个列表就有点复杂了。
1 个回答
7
假设你安装了Python 2.6或更高版本:
>>> from itertools import combinations
>>>
>>> data = dict(
... list1 = set(list("alphabet")),
... list2 = set(list("fiddlesticks")),
... list3 = set(list("geography")),
... list4 = set(list("bovinespongiformencephalopathy")),
... )
>>>
>>> variations = {}
>>> for i in range(len(data)):
... for v in combinations(data.keys(),i+1):
... vsets = [ data[x] for x in v ]
... variations[tuple(sorted(v))] = reduce(lambda x,y: x.intersection(y), vsets)
...
>>> for k,v in sorted(variations.items(),key=lambda x: (len(x[0]),x[0])):
... print "%r\n\t%r" % (k,v)
...
('list1',)
set(['a', 'b', 'e', 'h', 'l', 'p', 't'])
('list2',)
set(['c', 'e', 'd', 'f', 'i', 'k', 'l', 's', 't'])
('list3',)
set(['a', 'e', 'g', 'h', 'o', 'p', 'r', 'y'])
('list4',)
set(['a', 'c', 'b', 'e', 'g', 'f', 'i', 'h', 'm', 'l', 'o', 'n', 'p', 's', 'r', 't', 'v', 'y'])
('list1', 'list2')
set(['e', 'l', 't'])
('list1', 'list3')
set(['a', 'h', 'e', 'p'])
('list1', 'list4')
set(['a', 'b', 'e', 'h', 'l', 'p', 't'])
('list2', 'list3')
set(['e'])
('list2', 'list4')
set(['c', 'e', 'f', 'i', 'l', 's', 't'])
('list3', 'list4')
set(['a', 'e', 'g', 'h', 'o', 'p', 'r', 'y'])
('list1', 'list2', 'list3')
set(['e'])
('list1', 'list2', 'list4')
set(['e', 'l', 't'])
('list1', 'list3', 'list4')
set(['a', 'h', 'e', 'p'])
('list2', 'list3', 'list4')
set(['e'])
('list1', 'list2', 'list3', 'list4')
set(['e'])