Msgstr "sample larger than population" in random.sample python

creating a simple generator of passes for myself, I noticed that if I want my population to be only numbers (0-9), which is a total of 10 options, if I want my length to be more than 10, it will not use any digits more then once and return the error "sample more than population".

Is it possible to maintain code but add / shorten lines of code to make it work? or should i use a random use choice?

import string import random z=int(raw_input("for: \n numbers only choose 1, \n letters only choose 2, \n letters and numbers choose 3, \n for everything choose 4:")) if z==1: x=string.digits elif z==2: x=string.letters elif z==3: x=string.letters+string.digits elif z==4: x=string.letters+string.digits+string.punctuation else: print "die in a fire" y=int(raw_input("How many passwords would you like?:")) v=int(raw_input("How long would you like the password to be?:")) for i in range(y): string="" for n in random.sample(x,v): string+=n print string 

tee

+10
python string random
source share
3 answers

The purpose of random.sample() is to randomly select a subset of the input sequence without selecting any items more than once. If there are no repetitions in your input sequence, you will not output either.

You are not looking for a subset; you need one random selection from the input sequence, repeated several times. Elements can be used several times. Use random.choice() in a loop for this:

 for i in range(y): string = ''.join([random.choice(x) for _ in range(v)]) print string 

This creates a string of length v , where characters from x can be used more than once.

Quick demo:

 >>> import string >>> import random >>> x = string.letters + string.digits + string.punctuation >>> v = 20 >>> ''.join([random.choice(x) for _ in range(v)]) 'Ms>V\\0Mf| W@R ,#/.P~Rv' >>> ''.join([random.choice(x) for _ in range(v)]) 'TsPnvN&qlm#mBj-!~}3W' >>> ''.join([random.choice(x) for _ in range(v)]) '{:dfE;VhR:=_~O*,QG<f' 
+12
source share

@Martijn Pieters is right. But since they are listed in https://docs.python.org/3.4/library/random.html :

A warning. The pseudo-random generators of this module should not be used for security purposes. Use os.urandom () or SystemRandom if you need a cryptographically secure pseudo random number generator.

and the purpose of this is to create passwords, I suggest this approach:

 import string import random set = string.letters + string.digits + string.punctuation length = 20 password = ''.join( [ random.SystemRandom().choice( set) for _ in range( length) ] ) print( password) 

Can anyone confirm that it is safer?

+2
source share

Starting with python_3.6 you can use random.choises(x, k=v) for your purposes. Returns a list of items selected from a replacement population. If the population is empty, an IndexError is raised.

0
source share

All Articles