Jd?dZddlZddlmZddlmZmZmZmZm Z m Z m Z m Z m Z mZddlZddlmZmZmZgdZdZd'dZd Zd(d Zd(d Zd Zefd ZdZeZdZdZ dZ!d(dZ"dZ# ddlm$Z%dZ$e#je$_n #e&$re#Z$YnwxYwd(dZ'dZ(dZ)dZ*d(dZ+d(dZ,d(dZ-d)dZ.ddd Z/d(d!Z0d"Z1d#Z2d$Z3d%Z4d&Z5dS)*aImported from the recipes section of the itertools documentation. All functions taken from the recipes section of the itertools library docs [1]_. Some backward-compatible usability improvements have been made. .. [1] http://docs.python.org/library/itertools.html#recipes N)deque) chain combinationscountcyclegroupbyislicerepeatstarmaptee zip_longest) randrangesamplechoice) all_equalconsumeconvolve dotproduct first_trueflattengrouper iter_exceptncyclesnthnth_combinationpadnonepad_nonepairwise partitionpowersetprependquantify#random_combination_with_replacementrandom_combinationrandom_permutationrandom_product repeatfunc roundrobintabulatetailtakeunique_everseenunique_justseenc<tt||S)zReturn first *n* items of the iterable as a list. >>> take(3, range(10)) [0, 1, 2] If there are fewer than *n* items in the iterable, all of them are returned. >>> take(10, range(3)) [0, 1, 2] )listr niterables \/opt/alt/python311/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/recipes.pyr+r+<s x## $ $$c<t|t|S)aReturn an iterator over the results of ``func(start)``, ``func(start + 1)``, ``func(start + 2)``... *func* should be a function that accepts one integer argument. If *start* is not specified it defaults to 0. It will be incremented each time the iterator is advanced. >>> square = lambda x: x ** 2 >>> iterator = tabulate(square, -3) >>> take(4, iterator) [9, 4, 1, 0] )mapr)functionstarts r3r)r)Ls xu & &&r4c>tt||S)zReturn an iterator over the last *n* items of *iterable*. >>> t = tail(3, 'ABCDEFG') >>> list(t) ['E', 'F', 'G'] maxlen)iterrr0s r3r*r*^s hq))) * **r4cn|t|ddStt|||ddS)aXAdvance *iterable* by *n* steps. If *n* is ``None``, consume it entirely. Efficiently exhausts an iterator without returning values. Defaults to consuming the whole iterator, but an optional second argument may be provided to limit consumption. >>> i = (x for x in range(10)) >>> next(i) 0 >>> consume(i, 3) >>> next(i) 4 >>> consume(i) >>> next(i) Traceback (most recent call last): File "", line 1, in StopIteration If the iterator has fewer items remaining than the provided limit, the whole iterator will be consumed. >>> i = (x for x in range(3)) >>> consume(i, 5) >>> next(i) Traceback (most recent call last): File "", line 1, in StopIteration Nrr:)rnextr )iteratorr1s r3rrisG@ y hq!!!!!! VHa # #T*****r4c@tt||d|S)zReturns the nth item or a default value. >>> l = range(10) >>> nth(l, 3) 3 >>> nth(l, 20, "zebra") 'zebra' N)r>r )r2r1defaults r3rrs  xD))7 3 33r4cbt|}t|dot|d S)z Returns ``True`` if all the elements are equal to each other. >>> all_equal('aaaa') True >>> all_equal('aaab') False TF)rr>)r2gs r3rrs/ A 4== /a//r4c<tt||S)zcReturn the how many times the predicate is true. >>> quantify([True, False, True]) 2 )sumr6)r2preds r3r"r"s s4"" # ##r4c<t|tdS)aReturns the sequence of elements and then returns ``None`` indefinitely. >>> take(5, pad_none(range(3))) [0, 1, 2, None, None] Useful for emulating the behavior of the built-in :func:`map` function. See also :func:`padded`. N)rr r2s r3rrs 6$<< ( ((r4c`tjtt||S)zvReturns the sequence elements *n* times >>> list(ncycles(["a", "b"], 3)) ['a', 'b', 'a', 'b', 'a', 'b'] )r from_iterabler tuple)r2r1s r3rrs%  veHooq99 : ::r4cRtttj||S)zcReturns the dot product of the two iterables. >>> dotproduct([10, 10], [20, 20]) 400 )rEr6operatormul)vec1vec2s r3rrs  s8<t,, - --r4c*tj|S)zReturn an iterator flattening one level of nesting in a list of lists. >>> list(flatten([[0, 1], [2, 3]])) [0, 1, 2, 3] See also :func:`collapse`, which can flatten multiple levels of nesting. )rrJ) listOfListss r3rrs  { + ++r4c||t|t|St|t||S)aGCall *func* with *args* repeatedly, returning an iterable over the results. If *times* is specified, the iterable will terminate after that many repetitions: >>> from operator import add >>> times = 4 >>> args = 3, 5 >>> list(repeatfunc(add, times, *args)) [8, 8, 8, 8] If *times* is ``None`` the iterable will not terminate: >>> from random import randrange >>> times = None >>> args = 1, 11 >>> take(6, repeatfunc(randrange, times, *args)) # doctest:+SKIP [2, 4, 8, 1, 8, 4] )r r )functimesargss r3r'r's9, }tVD\\*** 4e,, - --r4c#zKt|\}}t|dt||Ed{VdS)zReturns an iterator of paired items, overlapping, from the original >>> take(4, pairwise(count())) [(0, 1), (1, 2), (2, 3), (3, 4)] On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`. N)r r>zip)r2abs r3 _pairwiser[sJ x==DAqDMMM1ayyr4)rc#4Kt|Ed{VdSN)itertools_pairwiserHs r3rrs,%h///////////r4ct|trtjdt||}}t |g|z}t |d|iS)zCollect data into fixed-length chunks or blocks. >>> list(grouper('ABCDEFG', 3, 'x')) [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')] z+grouper expects iterable as first parameter fillvalue) isinstanceintwarningswarnDeprecationWarningr<r )r2r1r`rVs r3rrsa(C  " 9;M   8 NN a D T 2 2 22r4c'Kt|}td|D}|rI |D]}|Vn2#t$r%|dz}tt||}YnwxYw|GdSdS)aJYields an item from each iterable, alternating between them. >>> list(roundrobin('ABC', 'D', 'EF')) ['A', 'D', 'E', 'B', 'F', 'C'] This function produces the same output as :func:`interleave_longest`, but may perform better for some inputs (in particular when the number of iterables is small). c3>K|]}t|jVdSr])r<__next__).0its r3 zroundrobin..9s+88$r((#888888r4N)lenr StopIterationr ) iterablespendingnextsr>s r3r(r(,s)nnG 88i888 8 8E 2 2  dff   2 2 2 qLG&0011EEE 2 22222sA,A/.A/ctfd|D}t|\}}d|Dd|DfS)a Returns a 2-tuple of iterables derived from the input iterable. The first yields the items that have ``pred(item) == False``. The second yields the items that have ``pred(item) == True``. >>> is_odd = lambda x: x % 2 != 0 >>> iterable = range(10) >>> even_items, odd_items = partition(is_odd, iterable) >>> list(even_items), list(odd_items) ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9]) If *pred* is None, :func:`bool` is used. >>> iterable = [0, 1, False, True, '', ' '] >>> false_items, true_items = partition(None, iterable) >>> list(false_items), list(true_items) ([0, False, ''], [1, True, ' ']) Nc32K|]}||fVdSr])rixrFs r3rkzpartition..Zs/22ADDGGQ<222222r4c3$K|] \}}||V dSr]rtricondrus r3rkzpartition..]s+++yad+++++++r4c3$K|] \}}||V dSr]rtrws r3rkzpartition..^s+''ya$'''''''r4)boolr )rFr2 evaluationst1t2s` r3rrCse( |2222222K   FB++B+++''B''' r4ct|tjfdtt dzDS)aYields all possible subsets of the iterable. >>> list(powerset([1, 2, 3])) [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] :func:`powerset` will operate on iterables that aren't :class:`set` instances, so repeated elements in the input will produce repeated elements in the output. Use :func:`unique_everseen` on the input to avoid generating duplicates: >>> seq = [1, 1, 0] >>> list(powerset(seq)) [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)] >>> from more_itertools import unique_everseen >>> list(powerset(unique_everseen(seq))) [(), (1,), (0,), (1, 0)] c38K|]}t|VdSr])r)rirss r3rkzpowerset..vs-MMa|Aq11MMMMMMr4rl)r/rrJrangerm)r2rs @r3r r bsH& XA  MMMM5Q!;L;LMMM M MMr4c#Kt}|j}g}|j}|du}|D]H}|r ||n|} ||vr|||V&#t$r||vr|||VYEwxYwdS)a Yield unique elements, preserving order. >>> list(unique_everseen('AAAABBBCCDAABBB')) ['A', 'B', 'C', 'D'] >>> list(unique_everseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'D'] Sequences with a mix of hashable and unhashable items can be used. The function will be slower (i.e., `O(n^2)`) for unhashable items. Remember that ``list`` objects are unhashable - you can use the *key* parameter to transform the list to a tuple (which is hashable) to avoid a slowdown. >>> iterable = ([1, 2], [2, 3], [1, 2]) >>> list(unique_everseen(iterable)) # Slow [[1, 2], [2, 3]] >>> list(unique_everseen(iterable, key=tuple)) # Faster [[1, 2], [2, 3]] Similary, you may want to convert unhashable ``set`` objects with ``key=frozenset``. For ``dict`` objects, ``key=lambda x: frozenset(x.items())`` can be used. N)setaddappend TypeError) r2keyseenset seenset_addseenlist seenlist_adduse_keyelementks r3r,r,ys6eeG+KH?LoG  # 0CCLLL  A       Q    sA  A-,A-c ttttjdt ||S)zYields elements in order, ignoring serial duplicates >>> list(unique_justseen('AAAABBBCCDAABBB')) ['A', 'B', 'C', 'D', 'A', 'B'] >>> list(unique_justseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'A', 'D'] rl)r6r>rM itemgetterr)r2rs r3r-r-s3 tS,Q//31G1GHH I IIr4c#XK | |V |V #|$rYdSwxYw)aXYields results from a function repeatedly until an exception is raised. Converts a call-until-exception interface to an iterator interface. Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel to end the loop. >>> l = [0, 1, 2] >>> list(iter_except(l.pop, IndexError)) [2, 1, 0] Nrt)rT exceptionfirsts r3rrs[  %''MMM $&&LLL       s  ))c>tt|||S)a Returns the first true value in the iterable. If no true value is found, returns *default* If *pred* is not None, returns the first item for which ``pred(item) == True`` . >>> first_true(range(10)) 1 >>> first_true(range(10), pred=lambda x: x > 5) 6 >>> first_true(range(10), default='missing', pred=lambda x: x > 9) 'missing' )r>filter)r2rArFs r3rrs" tX&& 0 00r4rl)r cRd|D|z}td|DS)aDraw an item at random from each of the input iterables. >>> random_product('abc', range(4), 'XYZ') # doctest:+SKIP ('c', 3, 'Z') If *repeat* is provided as a keyword argument, that many items will be drawn from each iterable. >>> random_product('abcd', range(4), repeat=2) # doctest:+SKIP ('a', 2, 'd', 3) This equivalent to taking a random selection from ``itertools.product(*args, **kwarg)``. c,g|]}t|SrtrKripools r3 z"random_product..s * * *TU4[[ * * *r4c34K|]}t|VdSr])rrs r3rkz!random_product..s(00$000000r4r)r rVpoolss r3r&r&s9 + *T * * *V 3E 00%000 0 00r4ct|}|t|n|}tt||S)abReturn a random *r* length permutation of the elements in *iterable*. If *r* is not specified or is ``None``, then *r* defaults to the length of *iterable*. >>> random_permutation(range(5)) # doctest:+SKIP (3, 4, 0, 1, 2) This equivalent to taking a random selection from ``itertools.permutations(iterable, r)``. )rKrmr)r2rrs r3r%r%s8 ??DYD AA a ! !!r4ct|t}ttt ||}tfd|DS)zReturn a random *r* length subsequence of the elements in *iterable*. >>> random_combination(range(5), 3) # doctest:+SKIP (2, 3, 4) This equivalent to taking a random selection from ``itertools.combinations(iterable, r)``. c3(K|] }|V dSr]rtriirs r3rkz%random_combination..'**Qa******r4)rKrmsortedrr)r2rr1indicesrs @r3r$r$s[ ??D D AVE!HHa(())G ****'*** * **r4ct|ttfdt|D}tfd|DS)aSReturn a random *r* length subsequence of elements in *iterable*, allowing individual elements to be repeated. >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP (0, 0, 1, 2, 2) This equivalent to taking a random selection from ``itertools.combinations_with_replacement(iterable, r)``. c36K|]}tVdSr])r)rirr1s r3rkz6random_combination_with_replacement..s)44aYq\\444444r4c3(K|] }|V dSr]rtrs r3rkz6random_combination_with_replacement..rr4)rKrmrr)r2rrr1rs @@r3r#r#sg ??D D A444458844444G ****'*** * **r4ct|}t|}|dks||krtd}t|||z }t d|dzD]}|||z |zz|z}|dkr||z }|dks||krt g}|rS||z|z|dz |dz }}}||kr||z}|||z z|z|dz }}||k||d|z |St|S)aEquivalent to ``list(combinations(iterable, r))[index]``. The subsequences of *iterable* that are of length *r* can be ordered lexicographically. :func:`nth_combination` computes the subsequence at sort position *index* directly, without computing the previous subsequences. >>> nth_combination(range(5), 3, 5) (0, 3, 4) ``ValueError`` will be raised If *r* is negative or greater than the length of *iterable*. ``IndexError`` will be raised if the given *index* is invalid. rrl)rKrm ValueErrorminr IndexErrorr) r2rindexrr1crrresults r3rr"s8 ??D D A A1q55 A Aq1u A 1a!e__!! QOq  qyy    uzz F $a%1*a!eQUa1qjj QJEA;!#QUqAqjj  d26l### $ ==r4c$t|g|S)aYield *value*, followed by the elements in *iterator*. >>> value = '0' >>> iterator = ['1', '2', '3'] >>> list(prepend(value, iterator)) ['0', '1', '2', '3'] To prepend multiple values, see :func:`itertools.chain` or :func:`value_chain`. )r)valuer?s r3r!r!Ls %( # ##r4c#HKt|ddd}t|}tdg||z}t|t d|dz D]A}||t ttj ||VBdS)aBConvolve the iterable *signal* with the iterable *kernel*. >>> signal = (1, 2, 3, 4, 5) >>> kernel = [3, 2, 1] >>> list(convolve(signal, kernel)) [3, 8, 14, 20, 26, 14, 5] Note: the input arguments are not interchangeable, as the *kernel* is immediately consumed and stored. Nrrr:rl) rKrmrrr rrEr6rMrN)signalkernelr1windowrus r3rr[s6]]44R4 F F A A3q ! ! !A %F 66!QU++ , ,55 a#hlFF3344444455r4)rr])NN)6__doc__rc collectionsr itertoolsrrrrrr r r r r rMrandomrrr__all__r+r)r*rrrrzr"rrrrrr'r[rr^ ImportErrorrr(rr r,r-rrr&r%r$r#rr!rrtr4r3rsE                        ,,,,,,,,,,   B % % % ''''$+++%+%+%+%+P 4 4 4 4 0 0 0!$$$$ ) ) ) ;;;... , , ,....6    )888888 000!(HHHH 3 3 3 3 222.>NNN.****Z J J J J    *1111("#11111(""""$ + + + +++"'''T $ $ $55555s'A==BB