Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue #837. Graph.[subjects|objects|predicates] optionally return uniques. #1520

Merged
merged 8 commits into from Dec 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
148 changes: 119 additions & 29 deletions rdflib/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,35 +670,125 @@ def set(self, triple):
self.add((subject, predicate, object_))
return self

def subjects(self, predicate=None, object=None) -> Iterable[Node]:
"""A generator of subjects with the given predicate and object"""
for s, p, o in self.triples((None, predicate, object)):
yield s

def predicates(self, subject=None, object=None) -> Iterable[Node]:
"""A generator of predicates with the given subject and object"""
for s, p, o in self.triples((subject, None, object)):
yield p

def objects(self, subject=None, predicate=None) -> Iterable[Node]:
"""A generator of objects with the given subject and predicate"""
for s, p, o in self.triples((subject, predicate, None)):
yield o

def subject_predicates(self, object=None):
"""A generator of (subject, predicate) tuples for the given object"""
for s, p, o in self.triples((None, None, object)):
yield s, p

def subject_objects(self, predicate=None):
"""A generator of (subject, object) tuples for the given predicate"""
for s, p, o in self.triples((None, predicate, None)):
yield s, o

def predicate_objects(self, subject=None):
"""A generator of (predicate, object) tuples for the given subject"""
for s, p, o in self.triples((subject, None, None)):
yield p, o
def subjects(self, predicate=None, object=None, unique=False) -> Iterable[Node]:
"""A generator of (optionally unique) subjects with the given
predicate and object"""
if not unique:
for s, p, o in self.triples((None, predicate, object)):
yield s
else:
subs = set()
for s, p, o in self.triples((None, predicate, object)):
if s not in subs:
yield s
try:
subs.add(s)
except MemoryError as e:
logger.error(
f"{e}. Consider not setting parameter 'unique' to True"
)
raise

def predicates(self, subject=None, object=None, unique=False) -> Iterable[Node]:
"""A generator of (optionally unique) predicates with the given
subject and object"""
if not unique:
for s, p, o in self.triples((subject, None, object)):
yield p
else:
preds = set()
for s, p, o in self.triples((subject, None, object)):
if p not in preds:
yield p
try:
preds.add(p)
except MemoryError as e:
logger.error(
f"{e}. Consider not setting parameter 'unique' to True"
)
raise

def objects(self, subject=None, predicate=None, unique=False) -> Iterable[Node]:
"""A generator of (optionally unique) objects with the given
subject and predicate"""
if not unique:
for s, p, o in self.triples((subject, predicate, None)):
yield o
else:
objs = set()
for s, p, o in self.triples((subject, predicate, None)):
if o not in objs:
yield o
try:
objs.add(o)
except MemoryError as e:
logger.error(
f"{e}. Consider not setting parameter 'unique' to True"
)
raise

def subject_predicates(
self, object=None, unique=False
) -> Generator[Tuple[Node, Node], None, None]:
"""A generator of (optionally unique) (subject, predicate) tuples
for the given object"""
if not unique:
for s, p, o in self.triples((None, None, object)):
yield s, p
else:
subj_preds = set()
for s, p, o in self.triples((None, None, object)):
if (s, p) not in subj_preds:
yield s, p
try:
subj_preds.add((s, p))
except MemoryError as e:
logger.error(
f"{e}. Consider not setting parameter 'unique' to True"
)
raise

def subject_objects(
self, predicate=None, unique=False
) -> Generator[Tuple[Node, Node], None, None]:
"""A generator of (optionally unique) (subject, object) tuples
for the given predicate"""
if not unique:
for s, p, o in self.triples((None, predicate, None)):
yield s, o
else:
subj_objs = set()
for s, p, o in self.triples((None, predicate, None)):
if (s, o) not in subj_objs:
yield s, o
try:
subj_objs.add((s, o))
except MemoryError as e:
logger.error(
f"{e}. Consider not setting parameter 'unique' to True"
)
raise

def predicate_objects(
self, subject=None, unique=False
) -> Generator[Tuple[Node, Node], None, None]:
"""A generator of (optionally unique) (predicate, object) tuples
for the given subject"""
if not unique:
for s, p, o in self.triples((subject, None, None)):
yield p, o
else:
pred_objs = set()
for s, p, o in self.triples((subject, None, None)):
if (p, o) not in pred_objs:
yield p, o
try:
pred_objs.add((p, o))
except MemoryError as e:
logger.error(
f"{e}. Consider not setting parameter 'unique' to True"
)
raise

def triples_choices(self, triple, context=None):
subject, predicate, object_ = triple
Expand Down