d4ca9b9140e3f085b36609bb8dfdaea79c78e144
[SubU] /
1 from itertools import filterfalse
2
3
4 def unique_everseen(iterable, key=None):
5     "List unique elements, preserving order. Remember all elements ever seen."
6     # unique_everseen('AAAABBBCCDAABBB') --> A B C D
7     # unique_everseen('ABBCcAD', str.lower) --> A B C D
8     seen = set()
9     seen_add = seen.add
10     if key is None:
11         for element in filterfalse(seen.__contains__, iterable):
12             seen_add(element)
13             yield element
14     else:
15         for element in iterable:
16             k = key(element)
17             if k not in seen:
18                 seen_add(k)
19                 yield element
20
21
22 # copied from more_itertools 8.8
23 def always_iterable(obj, base_type=(str, bytes)):
24     """If *obj* is iterable, return an iterator over its items::
25
26         >>> obj = (1, 2, 3)
27         >>> list(always_iterable(obj))
28         [1, 2, 3]
29
30     If *obj* is not iterable, return a one-item iterable containing *obj*::
31
32         >>> obj = 1
33         >>> list(always_iterable(obj))
34         [1]
35
36     If *obj* is ``None``, return an empty iterable:
37
38         >>> obj = None
39         >>> list(always_iterable(None))
40         []
41
42     By default, binary and text strings are not considered iterable::
43
44         >>> obj = 'foo'
45         >>> list(always_iterable(obj))
46         ['foo']
47
48     If *base_type* is set, objects for which ``isinstance(obj, base_type)``
49     returns ``True`` won't be considered iterable.
50
51         >>> obj = {'a': 1}
52         >>> list(always_iterable(obj))  # Iterate over the dict's keys
53         ['a']
54         >>> list(always_iterable(obj, base_type=dict))  # Treat dicts as a unit
55         [{'a': 1}]
56
57     Set *base_type* to ``None`` to avoid any special handling and treat objects
58     Python considers iterable as iterable:
59
60         >>> obj = 'foo'
61         >>> list(always_iterable(obj, base_type=None))
62         ['f', 'o', 'o']
63     """
64     if obj is None:
65         return iter(())
66
67     if (base_type is not None) and isinstance(obj, base_type):
68         return iter((obj,))
69
70     try:
71         return iter(obj)
72     except TypeError:
73         return iter((obj,))