@@ -523,6 +523,49 @@ def equals(self, other, *, recursive=True, ordered=False):
523523 return False
524524 return True
525525
526+ def iter (self , obj = "nodes" , method = "dfs" , duplicates = False , key = None ):
527+ """Iterates the :class:Node objects in the subtree of self.
528+
529+ Args:
530+ obj: yield Node objects (use value "nodes", default) or Edge
531+ objects (use values "edges")
532+ method: do breadth-first iteration (use value "bfs") or depth-dirst
533+ iteration (value "dfs", default).
534+ duplicates: If True, may return the same object twice if it is
535+ encountered twice, because of the DAG structure which isn't
536+ necessarily a tree. If it is False, all objects will be yielded
537+ only the first time they are encountered. Defaults to False.
538+ key: boolean function that filters the iterable items. key function
539+ takes one argument (the item) and returns True if it should be
540+ returned to the user. If an item isn't returned, its subtree
541+ is still iterated. Defaults to None (returns all items).
542+
543+ Yields:
544+ a :class:Node or :class:Edge object according to the iteration
545+ parameters.
546+
547+ """
548+ if method not in ("dfs" , "bfs" ):
549+ raise ValueError ("method can be either 'dfs' or 'bfs'" )
550+ if obj not in ("nodes" , "edges" ):
551+ raise ValueError ("obj can be either 'nodes' or 'edges'" )
552+ processed = set ()
553+ if obj == 'nodes' :
554+ waiting = [self ]
555+ else :
556+ waiting = self ._outgoing [:]
557+ while len (waiting ):
558+ curr = waiting .pop (0 )
559+ if key is None or key (curr ):
560+ yield curr
561+ processed .add (curr )
562+ to_add = curr .children if obj == 'nodes' else list (curr .child )
563+ to_add = [x for x in to_add if duplicates or x not in processed ]
564+ if method == "bfs" :
565+ waiting .extend (to_add )
566+ else :
567+ waiting = to_add + waiting
568+
526569
527570class Layer :
528571 """Group of similar :class:Node objects in UCCA annotation graph.
0 commit comments