我正在创建这样的搜索,就像在python中查询一样,收集id并使用像whois数据库那样的名称来解析它们。
所以我们说这是我在.txt文件中的数据
["81448068", "jimmy"]
["69711823", "bob"]
["92739493", "kyle, jimmy"]
["96399981", "kyle"]
["40112089", "john, peter"]
["79784393", "matthew, chad"]
["749968","bob, jimmy"]
Id位于左侧列,右侧是与之关联的名称。 我将如何使用某种类型的while或for循环来搜索该数据,直到所有名称完全匹配?如果添加了任何数据,这个方法应该有效,我会告诉你我目前的情况,但是在一个更大的txt文件中有更多的名字它不会起作用
def getNames(name):
x = []
f = open("names.txt","r") # that data up there represents names.txt
for line in f.readlines():
rid,names = json.loads(line.strip())
if name in names:
x += names.split(", ")
return list(set(x))
我想将这些名称循环回到获取名称以获取与x中返回的名称相关联的更多名称,但是我必须手动添加另一个名称,因为有些类型的东西会循环这个直到找到与名称相关的所有匹配项?所以做getNames(“jimmy”)会返回,
["bob","jimmy","kyle"]
然后它将检查与bob相关的所有名称,所有与之关联的名称,直到没有更多关联,并且它也会为jimmy和Kyle执行此操作。
所以基本上,它会搜索初始名称,在这种情况下让我们使用吉米。它返回与“jimmy”相关联的名称,然后它将搜索与之关联的每个单独的名称,所以让它说它返回,[“bob”,“jimmy”,“kyle”] 然后它将采取bob,在名称中搜索具有该名称的所有名称,然后搜索所有这些名称并搜索所有这些名称,直到它执行所有名称,然后它会做jimmy做同样然后去Kyle做相同。我可以用for来做到这一点但是,我需要添加多个fors,具体取决于我想要搜索的范围,我将如何进行一段时间以便它执行数据直到找到所有匹配项。
答案 0 :(得分:2)
这非常有趣。我的基本策略是在处理文件时修复关联,而不是在事后进行搜索。我没有对它进行测试,但它应该可以工作,尽管有错误。
编辑:现在我已经测试了它。
档案names.txt
:
["81448068", "jimmy"]
["69711823", "bob"]
["92739493", "kyle, jimmy"]
["96399981", "kyle"]
["40112089", "john, kyle"]
["79784393", "matthew, chad"]
["749968" , "bob, jimmy"]
处理文件:
import json
def process_new_file(filename, associations=None):
if associations == None:
associations = {}
with open(filename, 'r') as f:
lines = f.readlines()
for line in lines:
rid, onames = json.loads(line.strip())
extras = set([x.strip() for x in onames.split(',')])
names = set()
while len(extras) > 0:
names.update(extras)
extras = set()
for name in names:
if not name in associations:
associations[name] = set()
extras.update(associations[name] - names)
for name in names:
associations[name].update(names)
return associations
if __name__ == '__main__':
associations = process_new_file('names.txt')
tmpl = '{:20}: {}'
for person in associations:
print tmpl.format(person, ', '.join(associations[person]))
输出:
jimmy : jimmy, bob, john, kyle
chad : matthew, chad
kyle : jimmy, bob, john, kyle
matthew : matthew, chad
bob : jimmy, bob, john, kyle
john : jimmy, bob, john, kyle
答案 1 :(得分:1)
这是eval可能更合适的情况。 eval()基本上是说取一串文本并将其视为python代码。因此,由于您的输入文件采用python列表的格式,因此它将计算为列表。 (请注意,您可以如下所示迭代文件的行。)
def generateAssociations():
associations = dict()
f = open("names.txt","r")
for line in f:
line = eval(line)
id = int(line[0])
names = line[1].split(',')
newNames = [name.strip() for name in names]
for name in newNames:
if name not in associations:
associations[name] = lineNames
else:
associations[name] = associations[name] + newNames
for key, value in associations.items():
associations[key] = set(value)
pprint.pprint(associations)
在您的示例数据上运行时,它会将其作为输出:
{'bob': {'jimmy', 'bob'},
'chad': {'matthew', 'chad'},
'jimmy': {'kyle', 'jimmy', 'bob'},
'john': {'john', 'peter'},
'kyle': {'jimmy', 'kyle'},
'matthew': {'matthew', 'chad'},
'peter': {'john', 'peter'}}
对于初级朋友来说,这是非常容易进一步扩展的。
答案 2 :(得分:1)
就解析文件而言,你做得很好。
至于搜索,你应该考虑改变你对整个主题的处理方式。 Python或任何语言都适用于实现业务逻辑,但在大多数情况下,它在搜索大数据存储方面并不是很好。所以如果你有1000个名字,Python会做一个不错的工作,但是一旦你开始进入1,000,000个名字,脚本就会爬到停止状态。
为了在大数据存储上进行有效搜索,这就是数据库的设计目标。因此,明智的方法是首先将txt文件中的所有数据转储到数据库中,然后根据需要进行查询。这将使您拥有最强大的解决方案,并允许您在将来轻松扩展它。如果你当前正在使用txt文件,你可能不需要一个完整的数据库,所以sqlite就足够了。如果您不知道Sqlite是单个文件中的完整SQL数据库。无需安装,无需配置,只需一个文件系统上的文件就可以了。 Python有一个很好的包装器,有很好的sqlite文档,所以如果你决定采用这条路线,那应该不是很困难。可以找到文档here。直接使用sqlite包装器的另一种方法是使用ORM(对象关系包装器),例如SQLAlchemy,但是如果您不熟悉数据库,并且因为您对数据库的使用会如此简单,我建议您只使用sqlite包装器直接。
答案 3 :(得分:1)
好的,这就是我的方法:(代码也可以在这里作为要点: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 $
答案 4 :(得分:0)
您可以输入以下内容创建无限循环:
loop = "loop"
while loop == "loop":
##your code here...
程序将永远循环while函数下面的任何内容。