I have a dict of Facebook friends that looks like this:
connections = {
0: set([3, 4]),
1: set([5]),
2: set([]),
3: set([0, 4, 6]),
4: set([0, 3]),
5: set([1]),
6: set([3])}
where this dict matches a person (i.e. 3) to his friends (0, 4, 6). Now, I want to create a set of "friend circles" such that EVERY PERSON in the friend circle is friends with EVERY OTHER PERSON in the friend circle. It should look like this:
{{0, 3, 4}, {3, 4}, {0, 4}, {0, 3}, {1, 5}, ...}
Is there a simple way to accomplish this?
答案 0 :(得分:2)
from itertools import chain, combinations, product
connections = {
0: set([3, 4]),
1: set([5]),
2: set([]),
3: set([0, 4, 6]),
4: set([0, 3]),
5: set([1]),
6: set([3])
}
# Generate initial friend circles a generator that yields (0, 3, 4), (1, 5), (2,) etc.
# Please keep in mind that this gets exhausted after one run,
# if you want to reuse friend_circles later just use a list ([] instead of ())
friend_circles = (tuple(set([k]+list(v))) for (k, v) in connections.iteritems())
# Slightly modified version of python powerset recipe
# https://docs.python.org/2/library/itertools.html#recipes
# min_size is to specify the minimum number of people required to form a circle (2 friends in your example).
# The function further filters the resulting powerset by checking that all the members of the circle are friends with each other.
def get_valid_circles(iterable, min_size):
s = list(iterable)
return [
combo for combo in chain.from_iterable(combinations(s, r) for r in xrange(min_size, len(s)+1))
if all(p2 in connections.get(p1, set()) for (p1, p2) in filter(lambda c: c[0] != c[1], product(combo, combo)))
]
# After retrieving all the valid circles you will end up with dupes as well as some empty sets of circles, so
# Filter the chain of circles and cast it into a set.
circles = set(
filter(None, chain(*(get_valid_circles(friend_circle, 2) for friend_circle in friend_circles)))
)
print "Final filtered circles"
print circles
# If you want the unfiltered results you can just use this:
# if you come up with an empty result here, see my note above on friend_circles generator
# print "Final unfiltered circles"
# print [get_valid_circles(friend_circle, 2) for friend_circle in friend_circles]
打印
Final filtered circles
set([(0, 3, 4), (1, 5), (3, 6), (0, 4), (0, 3), (3, 4)])
答案 1 :(得分:0)
您首先需要展开所有朋友集,因此对于人0
,他的朋友集会成为
{0,3}, {0,4}, {0,3,4}
人1
成为:
{1,5}
人3
成为:
{3,0}, {3,4}, {3,6}, {3,0,4}, {3,0.6}, {3,4,6}, {3,0,4,6}
一旦你扩展了所有这些,然后再次遍历每个人,并检查扩展好友集中的每个朋友,看看他们是否也包含相同的扩展好友集。如果朋友集中的每个朋友都包含该朋友集,则它是朋友圈。存储这些朋友圈。如果需要,可以通过检查是否有任何圆圈是其他圆圈来删除子圆圈。例如{0,3}
是{0,3,4}
的子集,因此可以将其删除。