I wrote a code that queries a data structure that contains various triples - 3-item tuples in the form subject-predicate-object. I wrote this code based on an exercise from Programming the Semantic Web textbook.
def query(clauses):
bindings = None
for clause in clauses:
bpos = {}
qc = []
for pos, x in enumerate(clause):
if x.startswith('?'):
qc.append(None)
bpos[x] = pos
else:
qc.append(x)
rows = list(triples(tuple(qc)))
if bindings == None:
# 1st pass
bindings = [{var: row[pos] for var, pos in bpos.items()}
for row in rows]
else:
# >2 pass, eliminate wrong bindings
for binding in bindings:
for row in rows:
for var, pos in bpos.items():
if var in binding:
if binding[var] != row[pos]:
bindings.remove(binding)
continue
else:
binding[var] = row[pos]
return bindings
The function invocation looks like:
bg.query([('?person','lives','Chiapas'),
('?person','advocates','Zapatism')])
The function triples inside it accepts 3-tuples and returns list of 3-tuples. It can be found at Refactor deeply nested if-else
The function query loops over each clause, tracks variables (strings that start with '?'), replaces them with None, invokes triples, receives rows, tries to fit values to existing bindings.
How can i simplify this code? How can i make it more functional-style, without nested for-loops, continue keyword and so on?