Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/test/test_itertools.py

    r2 r391  
    33from itertools import *
    44from weakref import proxy
     5from decimal import Decimal
     6from fractions import Fraction
    57import sys
    68import operator
     
    810import copy
    911import pickle
     12from functools import reduce
    1013maxsize = test_support.MAX_Py_ssize_t
    1114minsize = -maxsize-1
     
    109112                    yield tuple(pool[i] for i in indices)
    110113
     114        def combinations3(iterable, r):
     115            'Pure python version from cwr()'
     116            pool = tuple(iterable)
     117            n = len(pool)
     118            for indices in combinations_with_replacement(range(n), r):
     119                if len(set(indices)) == r:
     120                    yield tuple(pool[i] for i in indices)
     121
    111122        for n in range(7):
    112123            values = [5*x-12 for x in range(n)]
    113124            for r in range(n+2):
    114125                result = list(combinations(values, r))
    115                 self.assertEqual(len(result), 0 if r>n else fact(n) / fact(r) / fact(n-r)) # right number of combs
     126                self.assertEqual(len(result), 0 if r>n else fact(n) // fact(r) // fact(n-r)) # right number of combs
    116127                self.assertEqual(len(result), len(set(result)))         # no repeats
    117128                self.assertEqual(result, sorted(result))                # lexicographic order
     
    120131                    self.assertEqual(len(set(c)), r)                    # no duplicate elements
    121132                    self.assertEqual(list(c), sorted(c))                # keep original ordering
    122                     self.assert_(all(e in values for e in c))           # elements taken from input iterable
     133                    self.assertTrue(all(e in values for e in c))           # elements taken from input iterable
    123134                    self.assertEqual(list(c),
    124135                                     [e for e in values if e in c])      # comb is a subsequence of the input iterable
    125136                self.assertEqual(result, list(combinations1(values, r))) # matches first pure python version
    126137                self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version
    127 
    128         # Test implementation detail:  tuple re-use
     138                self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version
     139
     140    @test_support.impl_detail("tuple reuse is specific to CPython")
     141    def test_combinations_tuple_reuse(self):
    129142        self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)
    130143        self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)
     144
     145    def test_combinations_with_replacement(self):
     146        cwr = combinations_with_replacement
     147        self.assertRaises(TypeError, cwr, 'abc')       # missing r argument
     148        self.assertRaises(TypeError, cwr, 'abc', 2, 1) # too many arguments
     149        self.assertRaises(TypeError, cwr, None)        # pool is not iterable
     150        self.assertRaises(ValueError, cwr, 'abc', -2)  # r is negative
     151        self.assertEqual(list(cwr('ABC', 2)),
     152                         [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')])
     153
     154        def cwr1(iterable, r):
     155            'Pure python version shown in the docs'
     156            # number items returned:  (n+r-1)! / r! / (n-1)! when n>0
     157            pool = tuple(iterable)
     158            n = len(pool)
     159            if not n and r:
     160                return
     161            indices = [0] * r
     162            yield tuple(pool[i] for i in indices)
     163            while 1:
     164                for i in reversed(range(r)):
     165                    if indices[i] != n - 1:
     166                        break
     167                else:
     168                    return
     169                indices[i:] = [indices[i] + 1] * (r - i)
     170                yield tuple(pool[i] for i in indices)
     171
     172        def cwr2(iterable, r):
     173            'Pure python version shown in the docs'
     174            pool = tuple(iterable)
     175            n = len(pool)
     176            for indices in product(range(n), repeat=r):
     177                if sorted(indices) == list(indices):
     178                    yield tuple(pool[i] for i in indices)
     179
     180        def numcombs(n, r):
     181            if not n:
     182                return 0 if r else 1
     183            return fact(n+r-1) // fact(r) // fact(n-1)
     184
     185        for n in range(7):
     186            values = [5*x-12 for x in range(n)]
     187            for r in range(n+2):
     188                result = list(cwr(values, r))
     189
     190                self.assertEqual(len(result), numcombs(n, r))           # right number of combs
     191                self.assertEqual(len(result), len(set(result)))         # no repeats
     192                self.assertEqual(result, sorted(result))                # lexicographic order
     193
     194                regular_combs = list(combinations(values, r))           # compare to combs without replacement
     195                if n == 0 or r <= 1:
     196                    self.assertEqual(result, regular_combs)            # cases that should be identical
     197                else:
     198                    self.assertTrue(set(result) >= set(regular_combs))     # rest should be supersets of regular combs
     199
     200                for c in result:
     201                    self.assertEqual(len(c), r)                         # r-length combinations
     202                    noruns = [k for k,v in groupby(c)]                  # combo without consecutive repeats
     203                    self.assertEqual(len(noruns), len(set(noruns)))     # no repeats other than consecutive
     204                    self.assertEqual(list(c), sorted(c))                # keep original ordering
     205                    self.assertTrue(all(e in values for e in c))           # elements taken from input iterable
     206                    self.assertEqual(noruns,
     207                                     [e for e in values if e in c])     # comb is a subsequence of the input iterable
     208                self.assertEqual(result, list(cwr1(values, r)))         # matches first pure python version
     209                self.assertEqual(result, list(cwr2(values, r)))         # matches second pure python version
     210
     211    @test_support.impl_detail("tuple reuse is specific to CPython")
     212    def test_combinations_with_replacement_tuple_reuse(self):
     213        cwr = combinations_with_replacement
     214        self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1)
     215        self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1)
    131216
    132217    def test_permutations(self):
     
    177262            for r in range(n+2):
    178263                result = list(permutations(values, r))
    179                 self.assertEqual(len(result), 0 if r>n else fact(n) / fact(n-r))      # right number of perms
     264                self.assertEqual(len(result), 0 if r>n else fact(n) // fact(n-r))      # right number of perms
    180265                self.assertEqual(len(result), len(set(result)))         # no repeats
    181266                self.assertEqual(result, sorted(result))                # lexicographic order
     
    183268                    self.assertEqual(len(p), r)                         # r-length permutations
    184269                    self.assertEqual(len(set(p)), r)                    # no duplicate elements
    185                     self.assert_(all(e in values for e in p))           # elements taken from input iterable
     270                    self.assertTrue(all(e in values for e in p))           # elements taken from input iterable
    186271                self.assertEqual(result, list(permutations1(values, r))) # matches first pure python version
    187272                self.assertEqual(result, list(permutations2(values, r))) # matches second pure python version
     
    190275                    self.assertEqual(result, list(permutations(values)))       # test default r
    191276
    192         # Test implementation detail:  tuple re-use
     277    @test_support.impl_detail("tuple resuse is CPython specific")
     278    def test_permutations_tuple_reuse(self):
    193279        self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1)
    194280        self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1)
     281
     282    def test_combinatorics(self):
     283        # Test relationships between product(), permutations(),
     284        # combinations() and combinations_with_replacement().
     285
     286        for n in range(6):
     287            s = 'ABCDEFG'[:n]
     288            for r in range(8):
     289                prod = list(product(s, repeat=r))
     290                cwr = list(combinations_with_replacement(s, r))
     291                perm = list(permutations(s, r))
     292                comb = list(combinations(s, r))
     293
     294                # Check size
     295                self.assertEqual(len(prod), n**r)
     296                self.assertEqual(len(cwr), (fact(n+r-1) // fact(r) // fact(n-1)) if n else (not r))
     297                self.assertEqual(len(perm), 0 if r>n else fact(n) // fact(n-r))
     298                self.assertEqual(len(comb), 0 if r>n else fact(n) // fact(r) // fact(n-r))
     299
     300                # Check lexicographic order without repeated tuples
     301                self.assertEqual(prod, sorted(set(prod)))
     302                self.assertEqual(cwr, sorted(set(cwr)))
     303                self.assertEqual(perm, sorted(set(perm)))
     304                self.assertEqual(comb, sorted(set(comb)))
     305
     306                # Check interrelationships
     307                self.assertEqual(cwr, [t for t in prod if sorted(t)==list(t)]) # cwr: prods which are sorted
     308                self.assertEqual(perm, [t for t in prod if len(set(t))==r])    # perm: prods with no dups
     309                self.assertEqual(comb, [t for t in perm if sorted(t)==list(t)]) # comb: perms that are sorted
     310                self.assertEqual(comb, [t for t in cwr if len(set(t))==r])      # comb: cwrs without dups
     311                self.assertEqual(comb, filter(set(cwr).__contains__, perm))     # comb: perm that is a cwr
     312                self.assertEqual(comb, filter(set(perm).__contains__, cwr))     # comb: cwr that is a perm
     313                self.assertEqual(comb, sorted(set(cwr) & set(perm)))            # comb: both a cwr and a perm
     314
     315    def test_compress(self):
     316        self.assertEqual(list(compress(data='ABCDEF', selectors=[1,0,1,0,1,1])), list('ACEF'))
     317        self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))
     318        self.assertEqual(list(compress('ABCDEF', [0,0,0,0,0,0])), list(''))
     319        self.assertEqual(list(compress('ABCDEF', [1,1,1,1,1,1])), list('ABCDEF'))
     320        self.assertEqual(list(compress('ABCDEF', [1,0,1])), list('AC'))
     321        self.assertEqual(list(compress('ABC', [0,1,1,1,1,1])), list('BC'))
     322        n = 10000
     323        data = chain.from_iterable(repeat(range(6), n))
     324        selectors = chain.from_iterable(repeat((0, 1)))
     325        self.assertEqual(list(compress(data, selectors)), [1,3,5] * n)
     326        self.assertRaises(TypeError, compress, None, range(6))      # 1st arg not iterable
     327        self.assertRaises(TypeError, compress, range(6), None)      # 2nd arg not iterable
     328        self.assertRaises(TypeError, compress, range(6))            # too few args
     329        self.assertRaises(TypeError, compress, range(6), None)      # too many args
    195330
    196331    def test_count(self):
     
    200335        self.assertEqual(take(2, zip('abc',count(-1))), [('a', -1), ('b', 0)])
    201336        self.assertEqual(take(2, zip('abc',count(-3))), [('a', -3), ('b', -2)])
    202         self.assertRaises(TypeError, count, 2, 3)
     337        self.assertRaises(TypeError, count, 2, 3, 4)
    203338        self.assertRaises(TypeError, count, 'a')
    204339        self.assertEqual(list(islice(count(maxsize-5), 10)), range(maxsize-5, maxsize+5))
     
    211346        self.assertEqual(repr(c), 'count(-9)')
    212347        c.next()
     348        self.assertEqual(repr(count(10.25)), 'count(10.25)')
    213349        self.assertEqual(c.next(), -8)
    214350        for i in (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 10, sys.maxint-5, sys.maxint+5):
     
    224360            self.assertEqual(next(copy.deepcopy(c)), value)
    225361            self.assertEqual(next(pickle.loads(pickle.dumps(c))), value)
     362
     363    def test_count_with_stride(self):
     364        self.assertEqual(zip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)])
     365        self.assertEqual(zip('abc',count(start=2,step=3)),
     366                         [('a', 2), ('b', 5), ('c', 8)])
     367        self.assertEqual(zip('abc',count(step=-1)),
     368                         [('a', 0), ('b', -1), ('c', -2)])
     369        self.assertEqual(zip('abc',count(2,0)), [('a', 2), ('b', 2), ('c', 2)])
     370        self.assertEqual(zip('abc',count(2,1)), [('a', 2), ('b', 3), ('c', 4)])
     371        self.assertEqual(take(20, count(maxsize-15, 3)), take(20, range(maxsize-15, maxsize+100, 3)))
     372        self.assertEqual(take(20, count(-maxsize-15, 3)), take(20, range(-maxsize-15,-maxsize+100, 3)))
     373        self.assertEqual(take(3, count(2, 3.25-4j)), [2, 5.25-4j, 8.5-8j])
     374        self.assertEqual(take(3, count(Decimal('1.1'), Decimal('.1'))),
     375                         [Decimal('1.1'), Decimal('1.2'), Decimal('1.3')])
     376        self.assertEqual(take(3, count(Fraction(2,3), Fraction(1,7))),
     377                         [Fraction(2,3), Fraction(17,21), Fraction(20,21)])
     378        self.assertEqual(repr(take(3, count(10, 2.5))), repr([10, 12.5, 15.0]))
     379        c = count(3, 5)
     380        self.assertEqual(repr(c), 'count(3, 5)')
     381        c.next()
     382        self.assertEqual(repr(c), 'count(8, 5)')
     383        c = count(-9, 0)
     384        self.assertEqual(repr(c), 'count(-9, 0)')
     385        c.next()
     386        self.assertEqual(repr(c), 'count(-9, 0)')
     387        c = count(-9, -3)
     388        self.assertEqual(repr(c), 'count(-9, -3)')
     389        c.next()
     390        self.assertEqual(repr(c), 'count(-12, -3)')
     391        self.assertEqual(repr(c), 'count(-12, -3)')
     392        self.assertEqual(repr(count(10.5, 1.25)), 'count(10.5, 1.25)')
     393        self.assertEqual(repr(count(10.5, 1)), 'count(10.5)')           # suppress step=1 when it's an int
     394        self.assertEqual(repr(count(10.5, 1.00)), 'count(10.5, 1.0)')   # do show float values lilke 1.0
     395        for i in (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 10, sys.maxint-5, sys.maxint+5):
     396            for j in  (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 1, 10, sys.maxint-5, sys.maxint+5):
     397                # Test repr (ignoring the L in longs)
     398                r1 = repr(count(i, j)).replace('L', '')
     399                if j == 1:
     400                    r2 = ('count(%r)' % i).replace('L', '')
     401                else:
     402                    r2 = ('count(%r, %r)' % (i, j)).replace('L', '')
     403                self.assertEqual(r1, r2)
    226404
    227405    def test_cycle(self):
     
    353531        self.assertRaises(TypeError, izip, 3)
    354532        self.assertRaises(TypeError, izip, range(3), 3)
    355         # Check tuple re-use (implementation detail)
    356533        self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')],
    357534                         zip('abc', 'def'))
    358535        self.assertEqual([pair for pair in izip('abc', 'def')],
    359536                         zip('abc', 'def'))
     537
     538    @test_support.impl_detail("tuple reuse is specific to CPython")
     539    def test_izip_tuple_resuse(self):
    360540        ids = map(id, izip('abc', 'def'))
    361541        self.assertEqual(min(ids), max(ids))
     
    371551                [range(1000), range(0), range(3000,3050), range(1200), range(1500), range(0)],
    372552            ]:
    373             target = map(None, *args)
     553            # target = map(None, *args) <- this raises a py3k warning
     554            # this is the replacement:
     555            target = [tuple([arg[i] if i < len(arg) else None for arg in args])
     556                      for i in range(max(map(len, args)))]
    374557            self.assertEqual(list(izip_longest(*args)), target)
    375558            self.assertEqual(list(izip_longest(*args, **{})), target)
     
    383566        self.assertEqual(list(izip_longest('abcdef')), zip('abcdef'))
    384567
    385         self.assertEqual(list(izip_longest('abc', 'defg', **{})), map(None, 'abc', 'defg')) # empty keyword dict
     568        self.assertEqual(list(izip_longest('abc', 'defg', **{})),
     569                         zip(list('abc') + [None], 'defg'))  # empty keyword dict
    386570        self.assertRaises(TypeError, izip_longest, 3)
    387571        self.assertRaises(TypeError, izip_longest, range(3), 3)
     
    398582                self.fail('Did not raise Type in:  ' + stmt)
    399583
    400         # Check tuple re-use (implementation detail)
    401584        self.assertEqual([tuple(list(pair)) for pair in izip_longest('abc', 'def')],
    402585                         zip('abc', 'def'))
    403586        self.assertEqual([pair for pair in izip_longest('abc', 'def')],
    404587                         zip('abc', 'def'))
     588
     589    @test_support.impl_detail("tuple reuse is specific to CPython")
     590    def test_izip_longest_tuple_reuse(self):
    405591        ids = map(id, izip_longest('abc', 'def'))
    406592        self.assertEqual(min(ids), max(ids))
     
    506692            self.assertEqual(len(list(product(*args))), expected_len)
    507693
    508         # Test implementation detail:  tuple re-use
     694    @test_support.impl_detail("tuple reuse is specific to CPython")
     695    def test_product_tuple_reuse(self):
    509696        self.assertEqual(len(set(map(id, product('abc', 'def')))), 1)
    510697        self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1)
    511698
    512699    def test_repeat(self):
     700        self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a'])
    513701        self.assertEqual(zip(xrange(3),repeat('a')),
    514702                         [(0, 'a'), (1, 'a'), (2, 'a')])
     
    600788        self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1)
    601789
     790        # Issue #10323:  Less islice in a predictable state
     791        c = count()
     792        self.assertEqual(list(islice(c, 1, 3, 50)), [1])
     793        self.assertEqual(next(c), 3)
     794
    602795    def test_takewhile(self):
    603796        data = [1, 3, 5, 20, 2, 4, 6, 8]
     
    697890        a, b = tee('abc')
    698891        c, d = tee(a)
    699         self.assert_(a is c)
     892        self.assertTrue(a is c)
    700893
    701894        # test tee_new
     
    705898        self.assertRaises(TypeError, tnew, 10)
    706899        t3 = tnew(t1)
    707         self.assert_(list(t1) == list(t2) == list(t3) == list('abc'))
     900        self.assertTrue(list(t1) == list(t2) == list(t3) == list('abc'))
    708901
    709902        # test that tee objects are weak referencable
     
    714907        self.assertRaises(ReferenceError, getattr, p, '__class__')
    715908
     909    # Issue 13454: Crash when deleting backward iterator from tee()
     910    def test_tee_del_backward(self):
     911        forward, backward = tee(repeat(None, 20000000))
     912        any(forward)  # exhaust the iterator
     913        del backward
     914
    716915    def test_StopIteration(self):
    717916        self.assertRaises(StopIteration, izip().next)
     
    751950                         [(0,1,2), (0,1,3), (0,2,3), (1,2,3)])
    752951
     952    def test_combinations_with_replacement(self):
     953        self.assertEqual(list(combinations_with_replacement('ABC', 2)),
     954                         [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')])
     955
     956    def test_compress(self):
     957        self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))
     958
    753959    def test_count(self):
    754960        self.assertEqual(list(islice(count(10), 5)), [10, 11, 12, 13, 14])
     
    8301036        a = []
    8311037        self.makecycle(combinations([1,2,a,3], 3), a)
     1038
     1039    def test_combinations_with_replacement(self):
     1040        a = []
     1041        self.makecycle(combinations_with_replacement([1,2,a,3], 3), a)
     1042
     1043    def test_compress(self):
     1044        a = []
     1045        self.makecycle(compress('ABCDEF', [1,0,1,0,1,0]), a)
     1046
     1047    def test_count(self):
     1048        a = []
     1049        Int = type('Int', (int,), dict(x=a))
     1050        self.makecycle(count(Int(0), Int(1)), a)
    8321051
    8331052    def test_cycle(self):
     
    9831202            self.assertRaises(TypeError, list, chain(N(s)))
    9841203            self.assertRaises(ZeroDivisionError, list, chain(E(s)))
     1204
     1205    def test_compress(self):
     1206        for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
     1207            n = len(s)
     1208            for g in (G, I, Ig, S, L, R):
     1209                self.assertEqual(list(compress(g(s), repeat(1))), list(g(s)))
     1210            self.assertRaises(TypeError, compress, X(s), repeat(1))
     1211            self.assertRaises(TypeError, list, compress(N(s), repeat(1)))
     1212            self.assertRaises(ZeroDivisionError, list, compress(E(s), repeat(1)))
    9851213
    9861214    def test_product(self):
     
    11751403        # count is not subclassable...
    11761404        for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap,
    1177                     starmap, islice, takewhile, dropwhile, cycle):
     1405                    starmap, islice, takewhile, dropwhile, cycle, compress):
    11781406            class Subclass(cls):
    11791407                def __init__(self, newarg=None, *args):
     
    11831411            except TypeError, err:
    11841412                # we expect type errors because of wrong argument count
    1185                 self.failIf("does not take keyword arguments" in err.args[0])
     1413                self.assertNotIn("does not take keyword arguments", err.args[0])
    11861414
    11871415
     
    12291457# same group.
    12301458>>> data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
    1231 >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
     1459>>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]):
    12321460...     print map(operator.itemgetter(1), g)
    12331461...
     
    12631491
    12641492>>> def ncycles(iterable, n):
    1265 ...     "Returns the seqeuence elements n times"
     1493...     "Returns the sequence elements n times"
    12661494...     return chain(*repeat(iterable, n))
    12671495
     
    13091537...     s = list(iterable)
    13101538...     return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
    1311 
    1312 >>> def compress(data, selectors):
    1313 ...     "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"
    1314 ...     return (d for d, s in izip(data, selectors) if s)
    1315 
    1316 >>> def combinations_with_replacement(iterable, r):
    1317 ...     "combinations_with_replacement('ABC', 3) --> AA AB AC BB BC CC"
    1318 ...     pool = tuple(iterable)
    1319 ...     n = len(pool)
    1320 ...     if not n and r:
    1321 ...         return
    1322 ...     indices = [0] * r
    1323 ...     yield tuple(pool[i] for i in indices)
    1324 ...     while 1:
    1325 ...         for i in reversed(range(r)):
    1326 ...             if indices[i] != n - 1:
    1327 ...                 break
    1328 ...         else:
    1329 ...             return
    1330 ...         indices[i:] = [indices[i] + 1] * (r - i)
    1331 ...         yield tuple(pool[i] for i in indices)
    13321539
    13331540>>> def unique_everseen(iterable, key=None):
     
    14141621[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
    14151622
    1416 >>> list(compress('abcdef', [1,0,1,0,1,1]))
    1417 ['a', 'c', 'e', 'f']
    1418 
    1419 >>> list(combinations_with_replacement('abc', 2))
    1420 [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
    1421 
    1422 >>> list(combinations_with_replacement('01', 3))
    1423 [('0', '0', '0'), ('0', '0', '1'), ('0', '1', '1'), ('1', '1', '1')]
    1424 
    1425 >>> def combinations_with_replacement2(iterable, r):
    1426 ...     'Alternate version that filters from product()'
    1427 ...     pool = tuple(iterable)
    1428 ...     n = len(pool)
    1429 ...     for indices in product(range(n), repeat=r):
    1430 ...         if sorted(indices) == list(indices):
    1431 ...             yield tuple(pool[i] for i in indices)
    1432 
    1433 >>> list(combinations_with_replacement('abc', 2)) == list(combinations_with_replacement2('abc', 2))
     1623>>> all(len(list(powerset(range(n)))) == 2**n for n in range(18))
    14341624True
    14351625
    1436 >>> list(combinations_with_replacement('01', 3)) == list(combinations_with_replacement2('01', 3))
    1437 True
    1438 
    1439 >>> list(combinations_with_replacement('2310', 6)) == list(combinations_with_replacement2('2310', 6))
     1626>>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len)
    14401627True
    14411628
Note: See TracChangeset for help on using the changeset viewer.