Completed
Push — develop ( dd7bb4...1e2583 )
by Kale
01:09
created

firstitem()   B

Complexity

Conditions 5

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
dl 0
loc 2
rs 8.5454
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
"""Common collection classes."""
3
from __future__ import print_function, division, absolute_import
4
from functools import reduce
5
6
from .compat import text_type
7
8
9
# http://stackoverflow.com/a/14620633/2127762
10
class AttrDict(dict):
11
    """Sub-classes dict, and further allows attribute-like access to dictionary items.
12
13
    Examples:
14
        >>> d = AttrDict({'a': 1})
15
        >>> d.a, d['a'], d.get('a')
16
        (1, 1, 1)
17
        >>> d.b = 2
18
        >>> d.b, d['b']
19
        (2, 2)
20
    """
21
    def __init__(self, *args, **kwargs):
22
        super(AttrDict, self).__init__(*args, **kwargs)
23
        self.__dict__ = self
24
25
26
def first(seq, key=lambda x: bool(x), default=None, apply=lambda x: x):
27
    """Give the first value that satisfies the key test.
28
29
    Args:
30
        seq (iterable):
31
        key (callable): test for each element of iterable
32
        default: returned when all elements fail test
33
        apply (callable): applied to element before return
34
35
    Returns: first element in seq that passes key, mutated with optional apply
36
37
    Examples:
38
        >>> first([0, False, None, [], (), 42])
39
        42
40
        >>> first([0, False, None, [], ()]) is None
41
        True
42
        >>> first([0, False, None, [], ()], default='ohai')
43
        'ohai'
44
        >>> import re
45
        >>> m = first(re.match(regex, 'abc') for regex in ['b.*', 'a(.*)'])
46
        >>> m.group(1)
47
        'bc'
48
49
        The optional `key` argument specifies a one-argument predicate function
50
        like that used for `filter()`.  The `key` argument, if supplied, must be
51
        in keyword form.  For example:
52
        >>> first([1, 1, 3, 4, 5], key=lambda x: x % 2 == 0)
53
        4
54
55
    """
56
    return next((apply(x) for x in seq if key(x)), default)
57
58
59
def firstitem(map, key=lambda k, v: bool(k), default=None, apply=lambda k, v: (k, v)):
60
    return next((apply(k, v) for k, v in map if key(k, v)), default)
61
62
63
def last(seq, key=lambda x: bool(x), default=None, apply=lambda x: x):
64
    return next((apply(x) for x in reversed(seq) if key(x)), default)
65
66
67
def call_each(seq):
68
    """Calls each element of sequence to invoke the side effect.
69
70
    Args:
71
        seq:
72
73
    Returns: None
74
75
    """
76
    try:
77
        reduce(lambda _, y: y(), seq)
78
    except TypeError as e:
79
        if text_type(e) != "reduce() of empty sequence with no initial value":
80
            raise
81