我认为首先你需要改变你的输入:
"Name": [""] 建议寻找名称为空字符串的程序员。我认为你应该使用[] 而不是[""],或者类似的东西。
既然如此,那这个呢?
return_list = []
for row in data:
if all((getattr(row, k) in v) or (not v) for k, v in filter_dictionary.iteritems()):
return_list.append(thing)
你当前的代码是这样的:
return_list = []
for row in data:
if any((getattr(row, k) in v) or (not v) for k, v in filter_dictionary.iteritems()):
return_list.append(thing)
我认为以上方法或多或少是最好的方法(除了使用数据库)。
但是既然你建议了套...
首先你需要确保你的数据行类支持散列:
class Person:
def __init__(self, Name, Location, Job):
self.Name = Name
self.Location = Location
self.Job = Job
def __repr__(self):
return "Person({}, {}, {})".format(self.Name, self.Location, self.Job)
def __eq__(self, other):
return self.Name == other.Name and self.Location == other.Location and self.Job == other.Job
def __hash__(self):
return hash(repr(self))
然后这样做:
>>> from operator import itemgetter
>>> from itertools import product
>>> data
[Person(Bob, Salem, Programmer), Person(Steve, New York, Sales), Person(Jeff, New York, Programmer)]
>>> filter_dictionary = {"Name": [], "Job": ["Programmer"], "Location": ["Salem", "New York"]}
>>> fd = {key: (value or [getattr(person, key) for person in data]) for key, value in filter_dictionary.items()}
>>> fd
{'Job': ['Programmer'], 'Location': ['Salem', 'New York'], 'Name': ['Bob', 'Steve', 'Jeff']}
>>> items = list(fd.iteritems())
>>> new = []
>>> for p in product(*map(itemgetter(1), items)):
temp = {}
for index, value in enumerate(p):
temp[items[index][0]] = value
new.append(temp)
>>> new
[{'Job': 'Programmer', 'Location': 'Salem', 'Name': 'Bob'}, {'Job': 'Programmer', 'Location': 'Salem', 'Name': 'Steve'}, {'Job': 'Programmer', 'Location': 'Salem', 'Name': 'Jeff'}, {'Job': 'Programmer', 'Location': 'New York', 'Name': 'Bob'}, {'Job': 'Programmer', 'Location': 'New York', 'Name': 'Steve'}, {'Job': 'Programmer', 'Location': 'New York', 'Name': 'Jeff'}]
>>> possible_matches = {Person(**kwargs) for kwargs in new}
>>> ts & set(data)
{Person(Bob, Salem, Programmer), Person(Jeff, New York, Programmer)}
如您所见,这更长,更麻烦。我不会推荐它。