"sample larger than population" in random.sample python
Since the python_3.6 you can use random.choices(x, k=v)
for your purpose. It returns a k sized list of elements chosen from the population with replacement. If the population is empty, raises IndexError.
@Martijn Pieters is right. But since they state at https://docs.python.org/3.4/library/random.html:
Warning: The pseudo-random generators of this module should not be used for security purposes. Use os.urandom() or SystemRandom if you require a cryptographically secure pseudo-random number generator.
and the purpose of this is for generating 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)
Could anybody please confirm that this is more secure?
The purpose of random.sample()
is to pick a subset of the input sequence, randomly, without picking any one element more than once. If your input sequence has no repetitions, neither will your output.
You are not looking for a subset; you want single random choices from the input sequence, repeated a number of times. Elements can be used more than once. 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'