diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 7b4c617..2eff470 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -13,7 +13,7 @@ Sequences Create :func:`count` :func:`cycle` :func:`repeat` :func:`repeatedly` :func:`iterate` :func:`re_all` :func:`re_iter` Access :func:`first` :func:`second` :func:`last` :func:`nth` :func:`some` :func:`take` Slice :func:`take` :func:`drop` :func:`rest` :func:`butlast` :func:`takewhile` :func:`dropwhile` :func:`split_at` :func:`split_by` -Transform :func:`map` :func:`mapcat` :func:`keep` :func:`pluck` :func:`pluck_attr` :func:`invoke` +Transform :func:`map` :func:`mapcat` :func:`keep` :func:`shuffled` :func:`pluck` :func:`pluck_attr` :func:`invoke` Filter :func:`filter` :func:`remove` :func:`keep` :func:`distinct` :func:`where` :func:`without` Join :func:`cat` :func:`concat` :func:`flatten` :func:`mapcat` :func:`interleave` :func:`interpose` Partition :func:`chunks` :func:`partition` :func:`partition_by` :func:`split_at` :func:`split_by` diff --git a/docs/seqs.rst b/docs/seqs.rst index 379f279..490fcae 100644 --- a/docs/seqs.rst +++ b/docs/seqs.rst @@ -170,6 +170,11 @@ This section provides some robust tools for sequence slicing. Consider :ref:`py3 Returns an iterator of all elements of the sequence but last. +.. function:: shuffled(seq) + + Returns a list of items of the sequence in random order. + + .. function:: ilen(seq) Calculates length of iterator. Will consume it or hang up if it's infinite. diff --git a/funcy/seqs.py b/funcy/seqs.py index 9a96252..cc1e57c 100644 --- a/funcy/seqs.py +++ b/funcy/seqs.py @@ -11,7 +11,7 @@ __all__ = [ - 'count', 'cycle', 'repeat', 'repeatedly', 'iterate', + 'count', 'cycle', 'repeat', 'repeatedly', 'iterate', 'shuffled', 'take', 'drop', 'first', 'second', 'nth', 'last', 'rest', 'butlast', 'ilen', 'map', 'filter', 'lmap', 'lfilter', 'remove', 'lremove', 'keep', 'lkeep', 'without', 'lwithout', 'concat', 'lconcat', 'chain', 'cat', 'lcat', 'flatten', 'lflatten', 'mapcat', 'lmapcat', @@ -34,6 +34,14 @@ def _lfilter(f, seq): # Re-export from itertools import count, cycle, repeat +import random + +def shuffled(seq): + """Returns a shuffled list of items in the sequence.""" + new_seq = list(seq) + # NOTE: random.shuffle() is done in place, which is why we copy the array + random.shuffle(new_seq) + return new_seq def repeatedly(f, n=EMPTY): """Takes a function of no args, presumably with side effects, diff --git a/tests/test_seqs.py b/tests/test_seqs.py index 4a4c0e6..6807a21 100644 --- a/tests/test_seqs.py +++ b/tests/test_seqs.py @@ -213,6 +213,11 @@ def test_sums(): assert lsums([1, 2, 3, 4]) == [1, 3, 6, 10] assert lsums([[1],[2],[3]]) == [[1], [1, 2], [1, 2, 3]] +def test_shuffled(): + assert sorted(shuffled([1, 2, 3])) == [1, 2, 3] + assert sorted(shuffled(range(3))) == [0, 1, 2] + assert isinstance(shuffled(range(3)), list) + def test_without(): assert lwithout([]) == [] assert lwithout([1, 2, 3, 4]) == [1, 2, 3, 4]