zeurosis
zeurosis

Reputation: 183

How to assign variable to string of elements in a list rather than those elements separately?

I'm having some trouble in regards to assigning a variable to a specific string of elements. Here's a simplified version of my code:

import random
import string

def printsl(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()



l = random.sample(string.ascii_lowercase, 26)
w = random.sample(l, random.randint(4, 10))

for elem in w:
    x = elem     #<------- 
    printsl(x)

print('')
printsl(x)

And when I run this code the output is something along the lines of

npabjcevz
z

or

znoyhe
e

etc.

The first line of output is what I wanted it to be, however for some reason the second line only prints the last letter of the string. Correct me if I'm wrong but I'm guessing it's because instead of elem equaling the whole string of random elements it gets reassigned to 4-10 different elements and prints all of them for printsl(x) under for elem in w but the second time it just uses the most recent letter.

How do I get it to print the full string both times? Or more specifically how to I get x to equal the entire string of output?

The only thing I could think of to try was changing x = elem to x = str(elem) but it gave the same result.

Upvotes: 0

Views: 134

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122092

Yes, you are producing a separate list of characters here, because random.sample() always returns a list:

l = random.sample(string.ascii_lowercase, 26)
w = random.sample(l, random.randint(4, 10))

The first line picks a list of 26 unique and random characters from the sequence string.ascii_lowercase. That the input is also 26 characters long means you basically have produced a randomly shuffled list of the 26 letters of the alphabet. The second line then picks between 4 and 10 characters from that shuffled list, shuffling those again.

You are confusing yourself somewhat by using a custom printls function that does not add newlines after everything it prints, so each character the for elem in w: loop prints appears right after the previous one. The for loop variable elem ends up being bound to the last character from the w list when the loop is complete.

You could get the same result by using random.sample() once, directly on string.ascii_lowercase

w = random.sample(string.ascii_lowercase, random.randint(4, 10))

This is still a list but you can just join the result back into a single string with str.join():

result = ''.join(w)

Now, usually when people pick random characters from string.ascii_lowercase they don't mind if characters repeat. You'll get a better password if you do, for example. Use the random.choice() function to pick one random character at a time, and repeat this process in a loop to pick your desired number of letters. A list comprehension can make this easier, putting all the results into a list, you'll have to join the result again:

result = ''.join([random.choice(string.ascii_lowercase)
                  for _ in range(random.randint(4, 10))])

Upvotes: 2

Related Questions