NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

itertoolsext.py (7829B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\brennivin\itertoolsext.py
      2 import datetime as _datetime
      3 import copy
      4 from itertools import *
      5 import random as _random
      6 from . import compat as _compat
      7 from .dochelpers import identity as _identity, default as _unsupplied
      8 if _compat.PY3K:
      9     ifilter = filter
     10     izip = zip
     11     izip_longest = zip_longest
     12 
     13 class Bundle(dict):
     14 
     15     def __init__(self, seq = None, **kwargs):
     16         dict.__init__(self, (seq or ()), **kwargs)
     17 
     18     def __getattr__(self, item):
     19         try:
     20             return self[item]
     21         except KeyError:
     22             raise AttributeError(item)
     23 
     24     def __setattr__(self, key, value):
     25         self[key] = value
     26 
     27     def __str__(self):
     28         clsn = self.__class__.__name__
     29         return '%s(%s)' % (clsn, dict.__repr__(self))
     30 
     31     __repr__ = __str__
     32 
     33     def __deepcopy__(self, memo = None, _nil = []):
     34         return Bundle(copy.deepcopy(dict(self)))
     35 
     36     def __hash__(self):
     37         return hash((tuple(self.keys()), tuple(self.values())))
     38 
     39 
     40 class FrozenDict(dict):
     41 
     42     def __raise(self, *args, **kwargs):
     43         raise TypeError()
     44 
     45     clear = pop = popitem = setdefault = update = __raise
     46     __delitem__ = __setitem__ = __raise
     47 
     48     def __hash__(self):
     49         if not hasattr(self, '_hash'):
     50             self._hash = 0
     51             for pair in self.items():
     52                 self._hash ^= hash(pair)
     53 
     54         return self._hash
     55 
     56 
     57 def all(seq, predicate = bool):
     58     for item in seq:
     59         if not predicate(item):
     60             return False
     61 
     62     return True
     63 
     64 
     65 def any(seq, predicate = bool):
     66     for item in seq:
     67         if predicate(item):
     68             return True
     69 
     70     return False
     71 
     72 
     73 def bucket(seq, keyprojection = _identity, valueprojection = _identity):
     74     result = {}
     75     for item in seq:
     76         thisbucket = result.setdefault(keyprojection(item), [])
     77         thisbucket.append(valueprojection(item))
     78 
     79     return result
     80 
     81 
     82 def count(seq, predicate = None):
     83     i = 0
     84     if predicate is None:
     85         try:
     86             return len(seq)
     87         except TypeError:
     88             pass
     89 
     90         for _ in seq:
     91             i += 1
     92 
     93     else:
     94         for item in seq:
     95             if predicate(item):
     96                 i += 1
     97 
     98     return i
     99 
    100 
    101 def datespan(startdate, enddate, delta = _datetime.timedelta(days=1)):
    102     if startdate < enddate:
    103         compare = lambda current, end: current < end
    104         increment = lambda current: current + delta
    105     else:
    106         compare = lambda current, end: current > end
    107         increment = lambda current: current - delta
    108     currentdate = startdate
    109     while compare(currentdate, enddate):
    110         yield currentdate
    111         currentdate = increment(currentdate)
    112 
    113 
    114 def first(seq, predicate = None):
    115     if predicate is None:
    116         return next(islice(seq, 1))
    117     filtered = ifilter(predicate, seq)
    118     return next(filtered)
    119 
    120 
    121 def first_or_default(seq, predicate = None, default = None):
    122     try:
    123         return first(seq, predicate)
    124     except StopIteration:
    125         return default
    126 
    127 
    128 def flatmap(function, sequence):
    129     for item in sequence:
    130         subseq = function(item)
    131         for subitem in subseq:
    132             yield subitem
    133 
    134 
    135 def groupby2(seq, keyfunc):
    136     sseq = sorted(seq, key=keyfunc)
    137     for key, group in groupby(sseq, keyfunc):
    138         yield (key, list(group))
    139 
    140 
    141 def groups_of_n(seq, n):
    142     evenlyDivisible = len(seq) % n == 0
    143     if not evenlyDivisible:
    144         msg = 'Sequence length %s not divisible by %s' % (len(seq), n)
    145         raise ArithmeticError(msg)
    146     return [ seq[i:i + n] for i in range(0, len(seq), n) ]
    147 
    148 
    149 def last(seq, predicate = None):
    150     lastitem = last_or_default(seq, predicate, _unsupplied)
    151     if lastitem is _unsupplied:
    152         raise StopIteration()
    153     return lastitem
    154 
    155 
    156 def last_or_default(seq, predicate = None, default = None):
    157     lastitem = default
    158     for item in seq:
    159         if predicate:
    160             if predicate(item):
    161                 lastitem = item
    162         else:
    163             lastitem = item
    164 
    165     return lastitem
    166 
    167 
    168 def single(seq):
    169     iterator = iter(seq)
    170     try:
    171         result = next(iterator)
    172     except StopIteration:
    173         raise
    174 
    175     try:
    176         next(iterator)
    177     except StopIteration:
    178         return result
    179 
    180     raise StopIteration('Sequence has more than one item.')
    181 
    182 
    183 def skip(sequence, number):
    184     cnt = 0
    185     for item in sequence:
    186         if cnt >= number:
    187             yield item
    188         else:
    189             cnt += 1
    190 
    191 
    192 def take(seq, number, predicate = None):
    193     if not isinstance(number, (int, float, _compat.long)):
    194         raise TypeError('number arg must be a number type.')
    195     yieldedcount = 0
    196     for item in seq:
    197         if yieldedcount >= number:
    198             break
    199         if predicate is None or predicate(item):
    200             yield item
    201             yieldedcount += 1
    202 
    203 
    204 def unique(seq, transform = _identity):
    205     seen = set()
    206     for item in seq:
    207         marker = transform(item)
    208         if marker in seen:
    209             continue
    210         seen.add(marker)
    211         yield item
    212 
    213 
    214 def treeyield_depthfirst(node, getchildren, getchild = None, yieldnode = False):
    215     if yieldnode:
    216         yield node
    217     childEnumerator = getchildren(node)
    218     if getchild:
    219         childEnumerator = range(childEnumerator)
    220     for child in childEnumerator:
    221         if getchild:
    222             child = getchild(node, child)
    223         for grandkid in treeyield_depthfirst(child, getchildren, getchild=getchild, yieldnode=True):
    224             yield grandkid
    225 
    226 
    227 def treeyield_breadthfirst(node, getchildren, getchild = None, yieldnode = False):
    228     if yieldnode:
    229         yield node
    230     childEnumerator = getchildren(node)
    231     if getchild:
    232         childEnumerator = range(childEnumerator)
    233     children = []
    234     for child in childEnumerator:
    235         if getchild:
    236             child = getchild(node, child)
    237         yield child
    238         children.append(child)
    239 
    240     for child in children:
    241         for grandkid in treeyield_breadthfirst(child, getchildren, getchild=getchild):
    242             yield grandkid
    243 
    244 
    245 def get_compound_item(collection, *indices):
    246     result = collection
    247     for ind in indices:
    248         result = result[ind]
    249 
    250     return result
    251 
    252 
    253 def set_compound_item(collection, value, *indices):
    254     operative = collection
    255     for ind in indices[:-1]:
    256         operative = operative[ind]
    257 
    258     operative[indices[-1]] = value
    259 
    260 
    261 def del_compound_item(collection, *indices):
    262     f = get_compound_item(collection, *indices[:-1])
    263     del f[indices[-1]]
    264 
    265 
    266 def _getattr_from_compound_element(obj, e):
    267     if isinstance(e, int):
    268         attr = obj[e]
    269     else:
    270         attr = getattr(obj, e)
    271     return attr
    272 
    273 
    274 def get_compound_attr(obj, *namesandindices):
    275     currentattr = obj
    276     for e in namesandindices:
    277         currentattr = _getattr_from_compound_element(currentattr, e)
    278 
    279     return currentattr
    280 
    281 
    282 def set_compound_attr(obj, value, *namesandindices):
    283     currentattr = obj
    284     for e in namesandindices[:-1]:
    285         currentattr = _getattr_from_compound_element(currentattr, e)
    286 
    287     setattr(currentattr, namesandindices[-1], value)
    288 
    289 
    290 def dict_add(alpha, beta, adder_function = None):
    291     if adder_function is None:
    292         adder_function = lambda value_a, value_b: value_a + value_b
    293     for key in beta:
    294         if key in alpha:
    295             alpha[key] = adder_function(alpha[key], beta[key])
    296         else:
    297             alpha[key] = beta[key]
    298 
    299 
    300 def shuffle(col, maxattempts = 5):
    301     ret = list(col)
    302     if not ret or len(ret) == 1:
    303         return ret
    304     attempts = 0
    305     while True:
    306         _random.shuffle(ret)
    307         if col != ret:
    308             return ret
    309         attempts += 1
    310         if attempts > maxattempts:
    311             raise AssertionError('Could not get a shuffle in %s attempts.' % maxattempts)
    312 
    313 
    314 def remove_duplicates_and_preserve_order(seq):
    315     seen = set()
    316     seen_add = seen.add
    317     return [ x for x in seq if not (x in seen or seen_add(x)) ]