好的,这就是我的做法:(代码也可以在这里作为要点:https ://gist.github.com/ychaouche/6894532 )
data = [
["81448068", "jimmy"],
["69711823", "bob"],
["92739493", "kyle, jimmy"],
["96399981", "kyle"],
["40112089", "john, kyle"],
["79784393", "matthew, chad"],
["749968" , "bob, jimmy"],
]
class MetaPerson(type):
_names_cache_ = {}
def __call__(cls,name):
return MetaPerson._names_cache_.setdefault(name,type.__call__(cls,name))
class Person(object):
__metaclass__ = MetaPerson
def __init__(self,name):
self.name = name
self.friends = []
def __repr__(self):
return "<Person '%s'>" % self.name
def add_friend(self,person):
if not person in self.friends :
self.friends.append(person)
if self not in person.friends:
person.add_friend(self)
def get_network(self,depth_limit=-1):
return [friend for friend in self.get_network_recursive(0,depth_limit,[self])]
def get_network_recursive(self,actual_depth,depth_limit,network):
if depth_limit != -1 and actual_depth > depth_limit:
return
if all((friend in network for friend in self.friends)):
return
for friend in self.friends :
if not friend in network :
yield friend
network.append(friend)
for friendsfriend in friend.get_network_recursive(actual_depth+1,depth_limit,network):
yield friendsfriend
class Population:
def __init__(self):
self.members = []
def find(self,name):
for member in self.members :
if member.name == name :
return member
def add_member(self,person):
if not person in self.members :
self.members.append(person)
def __repr__(self):
return repr(self.members)
def parse(data):
population = Population()
for tup in data :
names = tup[1].replace(" ","").split(",")
# will return an existing person if name is already taken
person1 = Person(names[0])
# add_member won't add if already present
population.add_member(person1)
if len(names) == 2 :
# will return an existing person if name is already taken
person2 = Person(names[1])
# add_member won't add if already present
population.add_member(person2)
person2.add_friend(person1)
return population
def main():
population = parse(data)
print "population",population
kyle = population.find("kyle")
print "Kyle's network : ",kyle.get_network(1)
def test():
antoine = Person("Antoine")
johny = Person("Johny")
patrick = Person("Patrick")
lisa = Person("Lisa")
johny.add_friend(antoine)
antoine.add_friend(patrick)
patrick.add_friend(lisa)
johny.add_friend(lisa)
print johny.get_network(1)
if __name__ == "__main__" :
main()
这是输出
chaouche@karabeela ~/CODE/TEST/PYTHON $ python findnames.py
population [<Person 'jimmy'>, <Person 'bob'>, <Person 'kyle'>, <Person 'john'>, <Person 'matthew'>, <Person 'chad'>]
Kyle's network : [<Person 'jimmy'>, <Person 'bob'>, <Person 'john'>]
chaouche@karabeela ~/CODE/TEST/PYTHON $
如果我将深度更改为 0(仅表示直接朋友),则输出更改为
chaouche@karabeela ~/CODE/TEST/PYTHON $ python findnames.py
population [<Person 'jimmy'>, <Person 'bob'>, <Person 'kyle'>, <Person 'john'>, <Person 'matthew'>, <Person 'chad'>]
Kyle's network : [<Person 'jimmy'>, <Person 'john'>]
chaouche@karabeela ~/CODE/TEST/PYTHON $