Package: handpick
HandpickHandpick is a tool to work with nested data structures.Installationpip install handpickQuick introductionThepickfunctionThepickgenerator function performs the recursive traversal
of a nested data structure and picks all objects that meet certain
criteria provided in the form of a predicate function.
Picked objects are retrieved lazily by an iterator.Simple predicate functionsThe predicate function is passed topickas thepredicateargument. For example:fromhandpickimportpickdefis_non_empty_string(obj):returnisinstance(obj,str)andobjdata=[[1,""],[-2,["foo",3.0]],-4,"bar"]>>> for s in pick(data, predicate=is_non_empty_string):
...     print(s)
...
foo
barHandling dictionary keysWhen traversing mappings like dictionaries, you can configure
whether or notpickwill examine dictionary keys by specifying
thedict_keyskeyword argument. Default is False, which means
only dictionary values are examined. For example:fromhandpickimportpickdata={"foo":{"name":"foo"},"bar":{"name":"bar"}}>>> for s in pick(data, predicate=lambda obj: "a" in obj):
...     print(s)
...
bar
>>> for s in pick(data, predicate=lambda obj: "a" in obj, dict_keys=True):
...     print(s)
...
name
bar
name
barPredicatesThePredicatedecoratorThePredicatedecorator wraps a function in an object that can be
combined with other predicates using the operators&(and) and|(or), as well as negated using the operator~(not).Combining predicatesFor example:fromhandpickimportpick,Predicate@Predicatedefis_integer(obj):returnisinstance(obj,int)@Predicatedefis_even(number):returnnumber%2==0data=[[4,[5.0,1],3.0],[[15,[]],{17:[7,[8],0]}]]# compound predicateodd_int=is_integer&~is_even>>> for n in pick(data, predicate=odd_int):
...     print(n)
...
1
15
7Combining predicates with functionsIn addition, the&and|operations are supported between
predicates and regular undecorated functions. For example:fromhandpickimportpick,Predicate@Predicatedefis_list(obj):returnisinstance(obj,list)data=[("1",[2]),{("x",):[(3,[4]),"5"]},["x",["6"]],{7:("x",)}]# compound predicateshort_list=(lambdaobj:len(obj)<2)&is_list>>> for l in pick(data, predicate=short_list):
...     print(l)
...
[2]
[4]
['6']Suppressing errorsThe important thing to note is that when the predicate’s underlying
function raises an exception, the exception is suppressed and the predicate
returns False. In other words, it is assumed that the object in question does
not meet the picking criteria. For example:fromhandpickimportpick,Predicate@Predicatedefabove_zero(number):returnnumber>0>>> above_zero(1)
True
>>> above_zero("a")
False
>>> for n in pick([[1, "Py", -2], [None, 3.0]], predicate=above_zero):
...     print(n)
...
1
3.0In the example above, several lists and strings were internally compared to0but noTypeErrorpropagated up to the code that calledabove_zero.Predicate factoriesTheis_typefunction can be used to create predicates based on
an object’s type. For example:fromhandpickimportpick,is_typedata=[[1.0,[2,True]],[False,[3]],["4"]]strictly_int=is_type(int)&~is_type(bool)>>> for n in pick(data, predicate=strictly_int):
...     print(n)
...
2
3Theno_errorfunction can be used to create predicates based on
whether a function applied to an object raises an error.fromhandpickimportpick,is_type,no_errordata={"name":"spam","price":"15.42","quantity":68,"year":"2011"}# strings that can be cast to floatsnumeric_str=is_type(str)&no_error(float)>>> for s in pick(data, predicate=numeric_str):
...     print(s)
...
15.42
2011Useful functionsThevalues_for_keyfunctionWhen inspecting data structures that contain dictionaries or other
mappings, you can usevalues_for_keyto retrieve values associated with
a specific key, regardless of the nested depth in which these values
are stored. Values are retrieved lazily by an iterator. For example:fromhandpickimportvalues_for_keydata={"node_id":4,"child_nodes":[{"node_id":8,"child_nodes":[{"node_id":16,},],},{"id":9,},],}>>> for i in values_for_key(data, key="node_id"):
...     print(i)
...
4
8
16Multiple keys may be specified at a time. For example:>>> for i in values_for_key(data, key=["node_id", "id"]):
...     print(i)
...
4
8
16
9Themax_depthfunctionThis function returns the maximum nested depth of a data structure. For
example:>>> from handpick import max_depth
>>> max_depth([0, [1, [2]]])
2
>>> max_depth({0: {1: {2: {3: {4: 4}}}}})
4Note:Just like non-empty collections, empty collections constitute
another level of nested depth. For example:>>> max_depth([0, [1, []]])
2RecipesFlattening nested dataTo flatten a list of lists, use thepickfunction without
thepredicateargument and passcollections=False. For example:fromhandpickimportpickdata=[[],[0],[[[],1],[2,[3,[4]],[]],[5]]]>>> list(pick(data, collections=False))
[0, 1, 2, 3, 4, 5]API referencepickhandpick.pick(data, predicate=None, *, collections=True, dict_keys=False, bytes_like=False)Pick objects fromdatabased onpredicate.Traversedatarecursively and yield all objects for whichpredicate(obj)is True or truthy.datashould be an iterable
collection.predicatemust be callable, must take one argument, and should
return a Boolean value. Ifpredicateis omitted or None, all objects
are picked.By default, collections of other objects are yielded just like any
other objects. To exclude collections, passcollections=False.When traversing a mapping, only its values are inspected by default.
To inspect both keys and values of mappings, passdict_keys=True.By default, bytes-like sequences (bytes and bytearrays) are not
treated as collections of other objects and therefore not iterated
by the recursive algorithm. This can be changed by passingbytes_like=True.Strings are not treated as collections of other objects and
therefore not iterated by the recursive algorithm.Predicate@handpick.Predicate(func=None, *, suppressed_errors=(TypeError, ValueError, LookupError, AttributeError))Decorator wrapping a function in a predicate object.The decorated function can be combined with other predicates using
the operators&(and) and|(or), as well as negated using the
operator~(not).suppressed_errorscan be used to customize which exception classes
will be suppressed by the predicate.Predicate objects are intended to be used as thepredicateargument to thepickfunction.is_typehandpick.is_type(type_or_types)Predicate factory. Return a predicate that returns True if
object is an instance of specified type(s).type_or_typesmust be a type or tuple of types.no_errorhandpick.no_error(func)Predicate factory. Return a predicate that returns True iffunccan be applied on object without an exception being raised,
False otherwise.values_for_keyhandpick.values_for_key(data, key)Pick values associated with a specific key.Traversedatarecursively and yield a sequence of dictionary
values that are mapped tokey.keymay be a list of multiple
keys.max_depthhandpick.max_depth(data)Return maximum nested depth ofdata.datashould be an iterable collection. Depth is counted from zero,
i.e. the direct elements ofdataare in depth 0.