Print a random anagram of a given stringSimple anagram or permutation generator in PythonGuessing a random number between a range of numbersRandom Distribution to fit an Average PythonRandom number generation seeding in C++Testing a Random number generatorGenerate cryptographically secure random numbers in a specific rangePython - Faster random business date generationTesting random number generator functionFrom a set of words, output all words that fit a string of random letters (like Scrabble)Split a given number so that their sum adds to another given numberPseudo-truly random number generator

How can an organ that provides biological immortality be unable to regenerate?

Is honey really a supersaturated solution? Does heating to un-crystalize redissolve it or melt it?

What does "^L" mean in C?

Am I eligible for the Eurail Youth pass? I am 27.5 years old

What is the plural TO / OF something

When to use snap-off blade knife and when to use trapezoid blade knife?

gerund and noun applications

Why is there so much iron?

I seem to dance, I am not a dancer. Who am I?

Matrix using tikz package

Light propagating through a sound wave

Do I need to consider instance restrictions when showing a language is in P?

Calculate the frequency of characters in a string

Comment Box for Substitution Method of Integrals

Can a wizard cast a spell during their first turn of combat if they initiated combat by releasing a readied spell?

What are substitutions for coconut in curry?

Hausdorff dimension of the boundary of fibres of Lipschitz maps

Could Sinn Fein swing any Brexit vote in Parliament?

What is the significance behind "40 days" that often appears in the Bible?

Practical application of matrices and determinants

Bash - pair each line of file

How could an airship be repaired midflight?

Have the tides ever turned twice on any open problem?

What favor did Moody owe Dumbledore?



Print a random anagram of a given string


Simple anagram or permutation generator in PythonGuessing a random number between a range of numbersRandom Distribution to fit an Average PythonRandom number generation seeding in C++Testing a Random number generatorGenerate cryptographically secure random numbers in a specific rangePython - Faster random business date generationTesting random number generator functionFrom a set of words, output all words that fit a string of random letters (like Scrabble)Split a given number so that their sum adds to another given numberPseudo-truly random number generator













6












$begingroup$


I am given a task to create a function that prints a random anagram of a given string:



def anagram(value):
'''Prints random anagram of given value'''
import random
newWord = ''
for i in range(len(value)):
pos = random.randint(0, len(value)-1)
newWord += value[pos]
value = value[:pos] + value[pos+1:]
print newWord


anagram('12345')
anagram('should')


What all edge cases should this program cover?










share|improve this question











$endgroup$











  • $begingroup$
    Possible duplicate of Simple anagram or permutation generator in Python
    $endgroup$
    – hjpotter92
    Jan 17 '18 at 16:47






  • 3




    $begingroup$
    @hjpotter92 Asking for a code review of code that solves the same problem as in some other question is fine here. Just having copy & pasted the other persons code would be a dupe (and also off-topic), or re-posting your own question (without having changed anything), instead of editing it.
    $endgroup$
    – Graipher
    Jan 17 '18 at 16:54






  • 1




    $begingroup$
    Is is acceptable to return the input string?
    $endgroup$
    – Eric Duminil
    Jan 17 '18 at 20:37















6












$begingroup$


I am given a task to create a function that prints a random anagram of a given string:



def anagram(value):
'''Prints random anagram of given value'''
import random
newWord = ''
for i in range(len(value)):
pos = random.randint(0, len(value)-1)
newWord += value[pos]
value = value[:pos] + value[pos+1:]
print newWord


anagram('12345')
anagram('should')


What all edge cases should this program cover?










share|improve this question











$endgroup$











  • $begingroup$
    Possible duplicate of Simple anagram or permutation generator in Python
    $endgroup$
    – hjpotter92
    Jan 17 '18 at 16:47






  • 3




    $begingroup$
    @hjpotter92 Asking for a code review of code that solves the same problem as in some other question is fine here. Just having copy & pasted the other persons code would be a dupe (and also off-topic), or re-posting your own question (without having changed anything), instead of editing it.
    $endgroup$
    – Graipher
    Jan 17 '18 at 16:54






  • 1




    $begingroup$
    Is is acceptable to return the input string?
    $endgroup$
    – Eric Duminil
    Jan 17 '18 at 20:37













6












6








6





$begingroup$


I am given a task to create a function that prints a random anagram of a given string:



def anagram(value):
'''Prints random anagram of given value'''
import random
newWord = ''
for i in range(len(value)):
pos = random.randint(0, len(value)-1)
newWord += value[pos]
value = value[:pos] + value[pos+1:]
print newWord


anagram('12345')
anagram('should')


What all edge cases should this program cover?










share|improve this question











$endgroup$




I am given a task to create a function that prints a random anagram of a given string:



def anagram(value):
'''Prints random anagram of given value'''
import random
newWord = ''
for i in range(len(value)):
pos = random.randint(0, len(value)-1)
newWord += value[pos]
value = value[:pos] + value[pos+1:]
print newWord


anagram('12345')
anagram('should')


What all edge cases should this program cover?







python python-2.x random






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 21 '18 at 0:51









Jamal

30.4k11121227




30.4k11121227










asked Jan 17 '18 at 16:41









Latika AgarwalLatika Agarwal

881426




881426











  • $begingroup$
    Possible duplicate of Simple anagram or permutation generator in Python
    $endgroup$
    – hjpotter92
    Jan 17 '18 at 16:47






  • 3




    $begingroup$
    @hjpotter92 Asking for a code review of code that solves the same problem as in some other question is fine here. Just having copy & pasted the other persons code would be a dupe (and also off-topic), or re-posting your own question (without having changed anything), instead of editing it.
    $endgroup$
    – Graipher
    Jan 17 '18 at 16:54






  • 1




    $begingroup$
    Is is acceptable to return the input string?
    $endgroup$
    – Eric Duminil
    Jan 17 '18 at 20:37
















  • $begingroup$
    Possible duplicate of Simple anagram or permutation generator in Python
    $endgroup$
    – hjpotter92
    Jan 17 '18 at 16:47






  • 3




    $begingroup$
    @hjpotter92 Asking for a code review of code that solves the same problem as in some other question is fine here. Just having copy & pasted the other persons code would be a dupe (and also off-topic), or re-posting your own question (without having changed anything), instead of editing it.
    $endgroup$
    – Graipher
    Jan 17 '18 at 16:54






  • 1




    $begingroup$
    Is is acceptable to return the input string?
    $endgroup$
    – Eric Duminil
    Jan 17 '18 at 20:37















$begingroup$
Possible duplicate of Simple anagram or permutation generator in Python
$endgroup$
– hjpotter92
Jan 17 '18 at 16:47




$begingroup$
Possible duplicate of Simple anagram or permutation generator in Python
$endgroup$
– hjpotter92
Jan 17 '18 at 16:47




3




3




$begingroup$
@hjpotter92 Asking for a code review of code that solves the same problem as in some other question is fine here. Just having copy & pasted the other persons code would be a dupe (and also off-topic), or re-posting your own question (without having changed anything), instead of editing it.
$endgroup$
– Graipher
Jan 17 '18 at 16:54




$begingroup$
@hjpotter92 Asking for a code review of code that solves the same problem as in some other question is fine here. Just having copy & pasted the other persons code would be a dupe (and also off-topic), or re-posting your own question (without having changed anything), instead of editing it.
$endgroup$
– Graipher
Jan 17 '18 at 16:54




1




1




$begingroup$
Is is acceptable to return the input string?
$endgroup$
– Eric Duminil
Jan 17 '18 at 20:37




$begingroup$
Is is acceptable to return the input string?
$endgroup$
– Eric Duminil
Jan 17 '18 at 20:37










2 Answers
2






active

oldest

votes


















5












$begingroup$

You should usually not put the imports into your functions. While Python does not re-import a module it has already imported, it still needs to run the check for this. So this introduces an unnecessary overhead, when running the function multiple times. There are a few use cases for doing this, though, like not wanting to pollute the global namespace if that module does some dirty hacks during its initialization or it takes a very long time to import and you only want to do this sometimes (and only run the function once). But random is no such module.




Your code makes this also too complicated. The biggest part of your algorithm is making sure that you don't re-use a letter you already used. You can use random.sample for this, instead. It randomly samples (duh) from an iterable (well it needs to be iterable and indexable, actually), without replacement:



import random

def anagram(value):
'''Returns random anagram of given value'''
return ''.join(random.sample(value, len(value)))


An alternative would be random.shuffle, which shuffles a list in place, but this has the overhead of casting to a list first. The documentation actually recommends using the first one (which is also a lot clearer IMO).



def anagram(value):
'''Returns random anagram of given value'''
value_list = list(value)
random.shuffle(value_list)
return ''.join(value_list)



As for corner cases to test? The obvious one is the empty string ''. Then maybe a string containing only one distinct letter, like 'aaa' (to catch some very weird algorithm that only looks at the set of letters, which would be quite wrong, of course). And then finally maybe the scaling behavior of the algorithm so strings of increasing length.



All should be tested for example with this:



from collections import Counter

def test_anagram_function(s):
assert Counter(s) == Counter(anagram(s))





share|improve this answer











$endgroup$




















    10












    $begingroup$

    • When building a string you should build a list, and then use ''.join(). This is as strings are immutable, and so generating newWord takes $O(n^2)$ time.

    • You are mannually poping pos from value. If you change value to a list, you can just use list.pop.

    • You should import random at the top of your code. Never in a function.

    • Common Python style is to use snake_case for variables.

    • Common Python style is to use _ as a throw away variable.

    • You can use random.randrange, rather than randint

    • It's best if you return rather than print your anagram.

    And so you could use:



    def anagram(value):
    new_word = []
    value = list(value)
    for _ in range(len(value)):
    pos = random.randrange(len(value))
    new_word.append(value.pop(pos))
    return ''.join(new_word)


    This however runs in $O(n^2)$ time. If you use a Fisher–Yates shuffle, you can do this in $O(n)$ time.



    def anagram(value):
    value = list(value)
    for i in range(len(value)):
    pos = random.randrange(i, len(value))
    value[i], value[pos] = value[pos], value[i]
    return ''.join(value)



    You can also use random.shuffle, which likely also uses the above algorithm. However you won't have to maintain it. Allowing:



    def anagram(value):
    value = list(value)
    random.shuffle(value)
    return ''.join(value)





    share|improve this answer











    $endgroup$












    • $begingroup$
      never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
      $endgroup$
      – яүυк
      Jan 17 '18 at 17:53






    • 4




      $begingroup$
      @MrGrj if you have circular imports you have much bigger problems than where your imports go.
      $endgroup$
      – Peilonrayz
      Jan 17 '18 at 17:55










    • $begingroup$
      Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
      $endgroup$
      – Eric Duminil
      Jan 17 '18 at 20:36






    • 2




      $begingroup$
      @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
      $endgroup$
      – Peilonrayz
      Jan 17 '18 at 20:41











    Your Answer





    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185328%2fprint-a-random-anagram-of-a-given-string%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5












    $begingroup$

    You should usually not put the imports into your functions. While Python does not re-import a module it has already imported, it still needs to run the check for this. So this introduces an unnecessary overhead, when running the function multiple times. There are a few use cases for doing this, though, like not wanting to pollute the global namespace if that module does some dirty hacks during its initialization or it takes a very long time to import and you only want to do this sometimes (and only run the function once). But random is no such module.




    Your code makes this also too complicated. The biggest part of your algorithm is making sure that you don't re-use a letter you already used. You can use random.sample for this, instead. It randomly samples (duh) from an iterable (well it needs to be iterable and indexable, actually), without replacement:



    import random

    def anagram(value):
    '''Returns random anagram of given value'''
    return ''.join(random.sample(value, len(value)))


    An alternative would be random.shuffle, which shuffles a list in place, but this has the overhead of casting to a list first. The documentation actually recommends using the first one (which is also a lot clearer IMO).



    def anagram(value):
    '''Returns random anagram of given value'''
    value_list = list(value)
    random.shuffle(value_list)
    return ''.join(value_list)



    As for corner cases to test? The obvious one is the empty string ''. Then maybe a string containing only one distinct letter, like 'aaa' (to catch some very weird algorithm that only looks at the set of letters, which would be quite wrong, of course). And then finally maybe the scaling behavior of the algorithm so strings of increasing length.



    All should be tested for example with this:



    from collections import Counter

    def test_anagram_function(s):
    assert Counter(s) == Counter(anagram(s))





    share|improve this answer











    $endgroup$

















      5












      $begingroup$

      You should usually not put the imports into your functions. While Python does not re-import a module it has already imported, it still needs to run the check for this. So this introduces an unnecessary overhead, when running the function multiple times. There are a few use cases for doing this, though, like not wanting to pollute the global namespace if that module does some dirty hacks during its initialization or it takes a very long time to import and you only want to do this sometimes (and only run the function once). But random is no such module.




      Your code makes this also too complicated. The biggest part of your algorithm is making sure that you don't re-use a letter you already used. You can use random.sample for this, instead. It randomly samples (duh) from an iterable (well it needs to be iterable and indexable, actually), without replacement:



      import random

      def anagram(value):
      '''Returns random anagram of given value'''
      return ''.join(random.sample(value, len(value)))


      An alternative would be random.shuffle, which shuffles a list in place, but this has the overhead of casting to a list first. The documentation actually recommends using the first one (which is also a lot clearer IMO).



      def anagram(value):
      '''Returns random anagram of given value'''
      value_list = list(value)
      random.shuffle(value_list)
      return ''.join(value_list)



      As for corner cases to test? The obvious one is the empty string ''. Then maybe a string containing only one distinct letter, like 'aaa' (to catch some very weird algorithm that only looks at the set of letters, which would be quite wrong, of course). And then finally maybe the scaling behavior of the algorithm so strings of increasing length.



      All should be tested for example with this:



      from collections import Counter

      def test_anagram_function(s):
      assert Counter(s) == Counter(anagram(s))





      share|improve this answer











      $endgroup$















        5












        5








        5





        $begingroup$

        You should usually not put the imports into your functions. While Python does not re-import a module it has already imported, it still needs to run the check for this. So this introduces an unnecessary overhead, when running the function multiple times. There are a few use cases for doing this, though, like not wanting to pollute the global namespace if that module does some dirty hacks during its initialization or it takes a very long time to import and you only want to do this sometimes (and only run the function once). But random is no such module.




        Your code makes this also too complicated. The biggest part of your algorithm is making sure that you don't re-use a letter you already used. You can use random.sample for this, instead. It randomly samples (duh) from an iterable (well it needs to be iterable and indexable, actually), without replacement:



        import random

        def anagram(value):
        '''Returns random anagram of given value'''
        return ''.join(random.sample(value, len(value)))


        An alternative would be random.shuffle, which shuffles a list in place, but this has the overhead of casting to a list first. The documentation actually recommends using the first one (which is also a lot clearer IMO).



        def anagram(value):
        '''Returns random anagram of given value'''
        value_list = list(value)
        random.shuffle(value_list)
        return ''.join(value_list)



        As for corner cases to test? The obvious one is the empty string ''. Then maybe a string containing only one distinct letter, like 'aaa' (to catch some very weird algorithm that only looks at the set of letters, which would be quite wrong, of course). And then finally maybe the scaling behavior of the algorithm so strings of increasing length.



        All should be tested for example with this:



        from collections import Counter

        def test_anagram_function(s):
        assert Counter(s) == Counter(anagram(s))





        share|improve this answer











        $endgroup$



        You should usually not put the imports into your functions. While Python does not re-import a module it has already imported, it still needs to run the check for this. So this introduces an unnecessary overhead, when running the function multiple times. There are a few use cases for doing this, though, like not wanting to pollute the global namespace if that module does some dirty hacks during its initialization or it takes a very long time to import and you only want to do this sometimes (and only run the function once). But random is no such module.




        Your code makes this also too complicated. The biggest part of your algorithm is making sure that you don't re-use a letter you already used. You can use random.sample for this, instead. It randomly samples (duh) from an iterable (well it needs to be iterable and indexable, actually), without replacement:



        import random

        def anagram(value):
        '''Returns random anagram of given value'''
        return ''.join(random.sample(value, len(value)))


        An alternative would be random.shuffle, which shuffles a list in place, but this has the overhead of casting to a list first. The documentation actually recommends using the first one (which is also a lot clearer IMO).



        def anagram(value):
        '''Returns random anagram of given value'''
        value_list = list(value)
        random.shuffle(value_list)
        return ''.join(value_list)



        As for corner cases to test? The obvious one is the empty string ''. Then maybe a string containing only one distinct letter, like 'aaa' (to catch some very weird algorithm that only looks at the set of letters, which would be quite wrong, of course). And then finally maybe the scaling behavior of the algorithm so strings of increasing length.



        All should be tested for example with this:



        from collections import Counter

        def test_anagram_function(s):
        assert Counter(s) == Counter(anagram(s))






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 17 '18 at 21:01

























        answered Jan 17 '18 at 16:59









        GraipherGraipher

        26.1k54091




        26.1k54091























            10












            $begingroup$

            • When building a string you should build a list, and then use ''.join(). This is as strings are immutable, and so generating newWord takes $O(n^2)$ time.

            • You are mannually poping pos from value. If you change value to a list, you can just use list.pop.

            • You should import random at the top of your code. Never in a function.

            • Common Python style is to use snake_case for variables.

            • Common Python style is to use _ as a throw away variable.

            • You can use random.randrange, rather than randint

            • It's best if you return rather than print your anagram.

            And so you could use:



            def anagram(value):
            new_word = []
            value = list(value)
            for _ in range(len(value)):
            pos = random.randrange(len(value))
            new_word.append(value.pop(pos))
            return ''.join(new_word)


            This however runs in $O(n^2)$ time. If you use a Fisher–Yates shuffle, you can do this in $O(n)$ time.



            def anagram(value):
            value = list(value)
            for i in range(len(value)):
            pos = random.randrange(i, len(value))
            value[i], value[pos] = value[pos], value[i]
            return ''.join(value)



            You can also use random.shuffle, which likely also uses the above algorithm. However you won't have to maintain it. Allowing:



            def anagram(value):
            value = list(value)
            random.shuffle(value)
            return ''.join(value)





            share|improve this answer











            $endgroup$












            • $begingroup$
              never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
              $endgroup$
              – яүυк
              Jan 17 '18 at 17:53






            • 4




              $begingroup$
              @MrGrj if you have circular imports you have much bigger problems than where your imports go.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 17:55










            • $begingroup$
              Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
              $endgroup$
              – Eric Duminil
              Jan 17 '18 at 20:36






            • 2




              $begingroup$
              @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 20:41
















            10












            $begingroup$

            • When building a string you should build a list, and then use ''.join(). This is as strings are immutable, and so generating newWord takes $O(n^2)$ time.

            • You are mannually poping pos from value. If you change value to a list, you can just use list.pop.

            • You should import random at the top of your code. Never in a function.

            • Common Python style is to use snake_case for variables.

            • Common Python style is to use _ as a throw away variable.

            • You can use random.randrange, rather than randint

            • It's best if you return rather than print your anagram.

            And so you could use:



            def anagram(value):
            new_word = []
            value = list(value)
            for _ in range(len(value)):
            pos = random.randrange(len(value))
            new_word.append(value.pop(pos))
            return ''.join(new_word)


            This however runs in $O(n^2)$ time. If you use a Fisher–Yates shuffle, you can do this in $O(n)$ time.



            def anagram(value):
            value = list(value)
            for i in range(len(value)):
            pos = random.randrange(i, len(value))
            value[i], value[pos] = value[pos], value[i]
            return ''.join(value)



            You can also use random.shuffle, which likely also uses the above algorithm. However you won't have to maintain it. Allowing:



            def anagram(value):
            value = list(value)
            random.shuffle(value)
            return ''.join(value)





            share|improve this answer











            $endgroup$












            • $begingroup$
              never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
              $endgroup$
              – яүυк
              Jan 17 '18 at 17:53






            • 4




              $begingroup$
              @MrGrj if you have circular imports you have much bigger problems than where your imports go.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 17:55










            • $begingroup$
              Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
              $endgroup$
              – Eric Duminil
              Jan 17 '18 at 20:36






            • 2




              $begingroup$
              @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 20:41














            10












            10








            10





            $begingroup$

            • When building a string you should build a list, and then use ''.join(). This is as strings are immutable, and so generating newWord takes $O(n^2)$ time.

            • You are mannually poping pos from value. If you change value to a list, you can just use list.pop.

            • You should import random at the top of your code. Never in a function.

            • Common Python style is to use snake_case for variables.

            • Common Python style is to use _ as a throw away variable.

            • You can use random.randrange, rather than randint

            • It's best if you return rather than print your anagram.

            And so you could use:



            def anagram(value):
            new_word = []
            value = list(value)
            for _ in range(len(value)):
            pos = random.randrange(len(value))
            new_word.append(value.pop(pos))
            return ''.join(new_word)


            This however runs in $O(n^2)$ time. If you use a Fisher–Yates shuffle, you can do this in $O(n)$ time.



            def anagram(value):
            value = list(value)
            for i in range(len(value)):
            pos = random.randrange(i, len(value))
            value[i], value[pos] = value[pos], value[i]
            return ''.join(value)



            You can also use random.shuffle, which likely also uses the above algorithm. However you won't have to maintain it. Allowing:



            def anagram(value):
            value = list(value)
            random.shuffle(value)
            return ''.join(value)





            share|improve this answer











            $endgroup$



            • When building a string you should build a list, and then use ''.join(). This is as strings are immutable, and so generating newWord takes $O(n^2)$ time.

            • You are mannually poping pos from value. If you change value to a list, you can just use list.pop.

            • You should import random at the top of your code. Never in a function.

            • Common Python style is to use snake_case for variables.

            • Common Python style is to use _ as a throw away variable.

            • You can use random.randrange, rather than randint

            • It's best if you return rather than print your anagram.

            And so you could use:



            def anagram(value):
            new_word = []
            value = list(value)
            for _ in range(len(value)):
            pos = random.randrange(len(value))
            new_word.append(value.pop(pos))
            return ''.join(new_word)


            This however runs in $O(n^2)$ time. If you use a Fisher–Yates shuffle, you can do this in $O(n)$ time.



            def anagram(value):
            value = list(value)
            for i in range(len(value)):
            pos = random.randrange(i, len(value))
            value[i], value[pos] = value[pos], value[i]
            return ''.join(value)



            You can also use random.shuffle, which likely also uses the above algorithm. However you won't have to maintain it. Allowing:



            def anagram(value):
            value = list(value)
            random.shuffle(value)
            return ''.join(value)






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 17 '18 at 17:11

























            answered Jan 17 '18 at 17:00









            PeilonrayzPeilonrayz

            25.9k338109




            25.9k338109











            • $begingroup$
              never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
              $endgroup$
              – яүυк
              Jan 17 '18 at 17:53






            • 4




              $begingroup$
              @MrGrj if you have circular imports you have much bigger problems than where your imports go.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 17:55










            • $begingroup$
              Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
              $endgroup$
              – Eric Duminil
              Jan 17 '18 at 20:36






            • 2




              $begingroup$
              @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 20:41

















            • $begingroup$
              never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
              $endgroup$
              – яүυк
              Jan 17 '18 at 17:53






            • 4




              $begingroup$
              @MrGrj if you have circular imports you have much bigger problems than where your imports go.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 17:55










            • $begingroup$
              Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
              $endgroup$
              – Eric Duminil
              Jan 17 '18 at 20:36






            • 2




              $begingroup$
              @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
              $endgroup$
              – Peilonrayz
              Jan 17 '18 at 20:41
















            $begingroup$
            never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
            $endgroup$
            – яүυк
            Jan 17 '18 at 17:53




            $begingroup$
            never” is a strong word. Sometimes, due to circular imports, you don’t have any other alternative:P (but of course it doesn’t apply in this scenario)
            $endgroup$
            – яүυк
            Jan 17 '18 at 17:53




            4




            4




            $begingroup$
            @MrGrj if you have circular imports you have much bigger problems than where your imports go.
            $endgroup$
            – Peilonrayz
            Jan 17 '18 at 17:55




            $begingroup$
            @MrGrj if you have circular imports you have much bigger problems than where your imports go.
            $endgroup$
            – Peilonrayz
            Jan 17 '18 at 17:55












            $begingroup$
            Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
            $endgroup$
            – Eric Duminil
            Jan 17 '18 at 20:36




            $begingroup$
            Just curious : why "never in a function"? It could make sense for a heavy_computation() function, which uses many libraries but whose result gets cached for later use.
            $endgroup$
            – Eric Duminil
            Jan 17 '18 at 20:36




            2




            2




            $begingroup$
            @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
            $endgroup$
            – Peilonrayz
            Jan 17 '18 at 20:41





            $begingroup$
            @EricDuminil The simple answer is PEP 8 says so. However, why wouldn't you make it a module? You can have it so it only loads when you do import module.submodule, just like a lot of the math and game libraries do. This has the benefit that it's cached without you having to do anything too.
            $endgroup$
            – Peilonrayz
            Jan 17 '18 at 20:41


















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185328%2fprint-a-random-anagram-of-a-given-string%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

            Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

            Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar