Skip to content

list_utils

trestle.common.list_utils ¤

Trestle List Utils.

Attributes¤

Classes¤

Functions¤

as_dict(dict_or_none) ¤

Convert dict or None object to itself or an empty dict if none.

Source code in trestle/common/list_utils.py
55
56
57
def as_dict(dict_or_none: Optional[Dict[TG, TG2]]) -> Dict[TG, TG2]:
    """Convert dict or None object to itself or an empty dict if none."""
    return dict_or_none if dict_or_none else {}

as_filtered_list(list_or_none, filter_condition) ¤

Convert to list and filter based on the condition.

Source code in trestle/common/list_utils.py
48
49
50
51
52
def as_filtered_list(list_or_none: Optional[List[TG]], filter_condition: Callable[[TG], bool]) -> List[TG]:
    """Convert to list and filter based on the condition."""
    result_list = as_list(list_or_none)
    result_list = list(filter(filter_condition, result_list))
    return result_list

as_list(list_or_none) ¤

Convert list or None object to itself or an empty list if none.

Source code in trestle/common/list_utils.py
23
24
25
def as_list(list_or_none: Optional[List[TG]]) -> List[TG]:
    """Convert list or None object to itself or an empty list if none."""
    return list_or_none if list_or_none else []

comma_colon_sep_to_dict(string_or_none) ¤

Convert optional comma and colon-sep list to dict.

Source code in trestle/common/list_utils.py
34
35
36
37
38
39
40
41
42
43
44
45
def comma_colon_sep_to_dict(string_or_none: Optional[str]) -> Dict[str, str]:
    """Convert optional comma and colon-sep list to dict."""
    entries = comma_sep_to_list(string_or_none)
    dic = {}
    for entry in entries:
        # if more than one colon include any colons in the value after the first one
        token = entry.split(':', 1)
        if len(token) == 1:
            dic[token[0].strip()] = token[0].strip()
        else:
            dic[token[0].strip()] = token[1].strip()
    return dic

comma_sep_to_list(string_or_none) ¤

Convert optional comma-sep string to list of strings and strip.

Source code in trestle/common/list_utils.py
28
29
30
31
def comma_sep_to_list(string_or_none: Optional[str]) -> List[str]:
    """Convert optional comma-sep string to list of strings and strip."""
    string_or_none = string_or_none.strip() if string_or_none else None
    return list(map(str.strip, string_or_none.split(','))) if string_or_none else []

deep_append(dic, path, value) ¤

Append to list in dict.

Source code in trestle/common/list_utils.py
174
175
176
177
178
179
180
181
182
183
def deep_append(dic: Dict[str, Any], path: List[str], value: Any) -> None:
    """Append to list in dict."""
    if not path:
        raise TrestleError('Error appending value in deep append with empty path.')
    for node in path[:-1]:
        dic[node] = dic.get(node, {})
        dic = dic[node]
    if path[-1] not in dic:
        dic[path[-1]] = []
    dic[path[-1]].append(value)

deep_get(dic, path, default=None) ¤

Get value from deep in dictionary.

Source code in trestle/common/list_utils.py
153
154
155
156
157
158
159
160
161
def deep_get(dic: Dict[str, Any], path: List[str], default: Any = None) -> Any:
    """Get value from deep in dictionary."""
    if not path:
        raise TrestleError('Error getting value in deep get with empty path.')
    for node in path[:-1]:
        if node not in dic:
            return default
        dic = dic[node]
    return dic.get(path[-1], default)

deep_set(dic, path, value, pop_if_none=True) ¤

Set value deep in dictionary.

pop_if_none will cause the key to be removed if value is None

Source code in trestle/common/list_utils.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def deep_set(dic: Dict[str, Any], path: List[str], value: Any, pop_if_none: bool = True) -> None:
    """
    Set value deep in dictionary.

    pop_if_none will cause the key to be removed if value is None
    """
    if not path:
        raise TrestleError('Error setting value in deep set with empty path.')
    for node in path[:-1]:
        dic[node] = dic.get(node, {})
        dic = dic[node]
    if value or not pop_if_none:
        dic[path[-1]] = value
    else:
        dic.pop(path[-1], None)

deep_update(dic, path, dic_value) ¤

Update the dict based on path.

Source code in trestle/common/list_utils.py
164
165
166
167
168
169
170
171
def deep_update(dic: Dict[str, Any], path: List[str], dic_value: Dict[str, Any]) -> None:
    """Update the dict based on path."""
    if not path:
        raise TrestleError('Error updating value in deep update with empty path.')
    for node in path:
        dic[node] = dic.get(node, {})
        dic = dic[node]
    dic.update(dic_value)

delete_item_from_list(item_list, value, key) ¤

Remove the first matching item if it is present in a list based on the callable key matching the query value.

Source code in trestle/common/list_utils.py
 94
 95
 96
 97
 98
 99
100
def delete_item_from_list(item_list: List[TG], value: TG2, key: Callable[[TG], TG2]) -> List[TG]:
    """Remove the first matching item if it is present in a list based on the callable key matching the query value."""
    keys = [key(item) for item in item_list]
    if value in keys:
        index = keys.index(value)
        del item_list[index]
    return item_list

delete_list_from_list(item_list, indices) ¤

Delete a list of items from a list based on indices.

Source code in trestle/common/list_utils.py
125
126
127
128
def delete_list_from_list(item_list: List[TG], indices: List[int]) -> None:
    """Delete a list of items from a list based on indices."""
    for index in sorted(indices, reverse=True):
        del item_list[index]

get_default(item, default) ¤

Return the default value for the item if it is not set.

Source code in trestle/common/list_utils.py
65
66
67
def get_default(item: TG, default: TG) -> TG:
    """Return the default value for the item if it is not set."""
    return item if item else default

get_item_from_list(item_list, value, key, remove=False) ¤

Get first item from list if present based on key matching value with option to remove it from the list.

Source code in trestle/common/list_utils.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def get_item_from_list(item_list: Optional[List[TG]],
                       value: TG2,
                       key: Callable[[TG], TG2],
                       remove: bool = False) -> Optional[TG]:
    """Get first item from list if present based on key matching value with option to remove it from the list."""
    if not item_list:
        return None
    keys = [key(item) for item in item_list]
    item = None
    if value in keys:
        index = keys.index(value)
        item = item_list[index]
        if remove:
            del item_list[index]
    return item

is_ordered_sublist(needle, haystack) ¤

Determine if needle is exactly contained in haystack.

The needle list comprises an ordered list of strings. The haystack list comprises an ordered list of strings that is to be searched. If the strings in the needle appear in the haystack in that exact order then return true, else false.

Examples: needle=['a','b','c'], haystack=['x','y','a','b','c','z'], result = True needle=['a','b','c'], haystack=['x','y','a','b','z','c'], result = False

Source code in trestle/common/list_utils.py
70
71
72
73
74
75
76
77
78
79
80
81
82
def is_ordered_sublist(needle: List[str], haystack: List[str]) -> bool:
    """Determine if needle is exactly contained in haystack.

    The needle list comprises an ordered list of strings.
    The haystack list comprises an ordered list of strings that is to be searched.
    If the strings in the needle appear in the haystack in that exact order then
    return true, else false.

    Examples:
    needle=['a','b','c'], haystack=['x','y','a','b','c','z'], result = True
    needle=['a','b','c'], haystack=['x','y','a','b','z','c'], result = False
    """
    return ' '.join(needle) in ' '.join(haystack)

join_key_to_list_dicts(dict1, dict2) ¤

Join two dicts of str to List.

Source code in trestle/common/list_utils.py
85
86
87
88
89
90
91
def join_key_to_list_dicts(dict1: Dict[str, List[Any]], dict2: Dict[str, List[Any]]) -> Dict[str, List[Any]]:
    """Join two dicts of str to List."""
    # merge like keys
    dict3 = {key: dict1[key] + dict2.get(key, []) for key in dict1}
    # merge unlike keys
    dict3.update({key: dict2[key] for key in dict2 if key not in dict3})
    return dict3

merge_dicts(dest, src) ¤

Merge the two dicts with priority to src.

Source code in trestle/common/list_utils.py
131
132
133
def merge_dicts(dest: Optional[Dict[str, str]], src: Optional[Dict[str, str]]) -> Dict[str, str]:
    """Merge the two dicts with priority to src."""
    return {**as_dict(dest), **as_dict(src)}

none_if_empty(list_) ¤

Convert to None if empty list.

Source code in trestle/common/list_utils.py
60
61
62
def none_if_empty(list_: List[TG]) -> Optional[List[TG]]:
    """Convert to None if empty list."""
    return list_ if list_ else None

pop_item_from_list(item_list, value, key) ¤

Pop first matching item from a list if it is present based on the key matching the value.

Source code in trestle/common/list_utils.py
120
121
122
def pop_item_from_list(item_list: Optional[List[TG]], value: TG2, key: Callable[[TG], TG2]) -> Optional[TG]:
    """Pop first matching item from a list if it is present based on the key matching the value."""
    return get_item_from_list(item_list, value, key, True)

set_or_pop(dic, key, value) ¤

Set if value is non-empty list or not None otherwise remove.

Source code in trestle/common/list_utils.py
186
187
188
189
190
191
def set_or_pop(dic: Dict[str, Any], key: str, value: Any) -> None:
    """Set if value is non-empty list or not None otherwise remove."""
    if value:
        dic[key] = value
    else:
        dic.pop(key, None)

handler: python