Listing words randomly without repeating them - python

I just finished learning how to do lists in python from the book,Python Programming for the Absolute Beginner, and came across a challenge asking to list out words randomly without repeating them. I have been trying to do it since the book doesn't gives you the answer to it. So far this is my code:
WORDS = ("YOU","ARE","WHO","THINK")
for word in WORDS:
newword=random.choice(WORDS)
while newword==word is False:
newword=random.choice(WORDS)
word=newword
print(word)
As obvious as it seems, the code didn't work out as the words repeat in lists.

You could use shuffle with a list instead of a tuple.
import random
lst = ['WHO','YOU','THINK','ARE']
random.shuffle(lst)
for x in lst:
print x
See this Q/A here also.
To convert a tuple to list: Q/A
The whole code if you insist on having a tuple:
import random
tuple = ('WHO','YOU','THINK','ARE')
lst = list(tuple)
random.shuffle(lst)
for x in lst:
print x

Add the printed word to a different array (e.g. 'usedwords') and loop through that array every time before you print another word.
Thats not perfomant but its a small list... so it should work just fine
(no code example, it should be in a beginners range to do that)

Related

How to divide the alphabet into lists of letters in a different way

I should divide the alphabet into lists of letters. I done that, my solution is good but my mentor said to me that I should a little improve this solution.
This is my code:
import string
import random
def generate_list():
list_of_letters=list(string.ascii_lowercase)
number_of_letter = len(list_of_letters)
main_list = []
while number_of_letter > 0:
a = random.randint(4, 7)
number_of_letter -= a
main_list.append(list_of_letters[0:a])
del list_of_letters[0:a]
print(main_list)
generate_list()
My mentor said me that I should take and remove lists of letters in one function, not to manually delete these pieces with lists of all letters manually using the del function So he would like to replace this fragment of code in one line.
main_list.append(list_of_letters[0:a])
del list_of_letters[0:a]
Can someone help me? Thank you in advance :)
You can use the pop() function of lists. It returns one item of the list and removes it from the list.
As it removes from the right side, in your case you have to specifically tell to take the list item at index 0 by calling pop(0).
So replacing your two lines from above with the following snippet should do everything in one step:
main_list.append([list_of_letters.pop(0) for _ in range(min(len(list_of_letters), a))])
Please note, that I stop popping elements from list_of_letters if a is larger then the remaining items in it, hence the min(len(list_of_letters), a).

Removing item from a list by a variable

Basicly im having problem with deleting an item from a list.
I'd like to to do it by a variable , somehow like this :
my_list = ["cat","dog","duck","horse","snake"]
import random
animal=(random.choice(my_list))
new_list = []
new_list.append(my_list)
new_list.remove(animal)
print(new_list)
and i get this :
ValueError : list.remove(x) : x not in list
What would you guys recommend me?
You've picked a random item from your list and then added the entire old list as a single element in your new list. This creates a two-dimensional list that does not contain any string values in the outermost list.
The best way to debug this is to print your list to see what it contains before applying the removal:
print(new_list) # => [['cat', 'dog', 'duck', 'horse', 'snake']]
Did you notice the extra [[]]? That's a nested list.
Likely, your intent was to copy the list (done here using the slice operator):
my_list = ["cat","dog","duck","horse","snake"]
import random
animal=(random.choice(my_list))
new_list = my_list[:]
new_list.remove(animal)
print(new_list)
Beyond this, it's good practice to include spaces, remove unnecessary parentheses and put imports at the top of files.
Lastly, remove is a linear operation that looks at potentially every element in the list to find the element you want to remove. This may seem silly, but when you begin working with lists of thousands or millions of items, it becomes a huge problem to walk the list unnecessarily.
Try using pop and random.randint to pick an index and remove it from the list in one stroke (you'll still incur a penalty for shifting list members around to fill in the gap; removing from the middle of a list isn't ideal):
import random
my_list = ["cat", "dog", "duck", "horse", "snake"]
new_list = my_list[:]
new_list.pop(random.randint(0, len(my_list) - 1))
print(new_list)
The above answer is adequate. However, I would point out that you can debug code another way, that being:
import pdb
and invoking in your function:
pdb.set_trace()
This basically allows you to enter the debugger at the calling stack frame. I find it much more resourceful.

Anagram generator from input in Python malfunction

I tried to code a simple generator of a list of anagrams from an input. But after I rewrote the code it gives me only 2 outputs. Here's the code
import random
item=input("Name? ")
a=''
b=''
oo=0
while oo<=(len(item)*len(item)):
a=''.join([str(y) for y in random.sample(item, len(item))]) #this line was found on this site
b=''.join([str(w) for w in random.sample(item, len(item))]) #because in no way i had success in doing it by myself
j=[]
j.append(a) #During the loop it should add the anagrams generated
j.append(b) #everytime the loop repeats itself
oo=oo+1
j=list(set(j)) #To cancel duplicates
h=len(j)
f=0
while f<=(h-1):
print(j[f])
But the output it gives is only one anagram repeated for ever.
As far as I can see you don't increment f at the end.
Do it rather like:
for item in j:
print( item )
The other thing is, you overwrite j in every loop. Are you sure you wanted it like that?
There were several problems with your loop construct, including reinitializing your results every time. Try a simpler approach where things are already the type they want to be rather than constantly converting. And not everything you want to do requires a loop:
import random
item = input("Name? ")
length = len(item)
anagrams = set()
for repetitions in range(length**2):
anagrams.add(''.join(random.sample(item, length)))
print("\n".join(anagrams))
However, these anagrams are not exhaustive (the random nature of this means some will be missed.) And they're not really anagrams as there's no dictionary to help generate actual words, just random letters.

Python anonymization using random.shuffle a list in a list

Here is my coding:
word = ma['vals']
shuffled = list(word)
random.shuffle(word)
shuffled = ''.join(random.sample(word, len(word)))
newval = shuffled
the result will be BALLOONSFLOWERSGIFTSFLOWERSCANDYFLOWERSBALLOONSBALLOONS. When I want the result to be for eg if i'm shuffling gifts, e result will be stgfi.
This is too long for a comment, so I'll put it in as an answer, although it isn't.
I'm sorry, please don't take this the wrong way, but this is the worst code I've seen in 15 years. You should probably go through a basic tutorial at least once more to get a better grip on what is happening, because this feels to me like you are just randomly typing things without trying to understand what they do.
Let's start from the beginning:
ma['vals'] = [balloons, flowers, gifts, candy]
OK, so I assume ma is a dictionary. You use that dictionary nowehere in the code. Why is it there?
word = ma['vals']
Now you just set word to [balloons, flowers, gifts, candy]. Why not do that directly? Also, don't call a list of words "word". That implies that it is one word, but you made it a list.
shuffled = list(word)
Why do you do list(word)? It's already a list. All you have done now is set:
shuffled = [balloons, flowers, gifts, candy]
And you call it shuffled, when it's not.
random.shuffle(word)
And now you shuffle it. But you didn't use the shuffled variable, you used the word variable.
shuffled = ''.join(random.sample(word, len(word)))
And now you set shuffled to another thing, so you never used the first shuffled. besides, making a random sample from a list that is as long as the list, is the same things as shuffling it, and the list is already shuffled.
newval = shuffled
Why did you do this?
All your code can in fact be compressed into:
newval = [balloons, flowers, gifts, candy]
random.shuffle(newval)
This will have the same end result: You will have a randomly shuffled list of words.
So two thirds of your code actually end up not doing anything. The above also makes it quite clear why your code doesn't behave like you think. You shuffle a list of words, when you want to shuffle a word.
If you want to randomly choose a word, and then randomly shuffle the letters of that word:
In [27]: letters = list(random.choice(word))
In [28]: random.shuffle(letters)
In [29]: ''.join(letters)
Out[29]: 'blanolos'
Here, word is the same variable as in your script (i.e. the list of words).
You must create a list from a string. In your case for example, the string "balloons" would be accessed by ma["vals"][0]. You can then convert this to a list via calling list and passing in the string. The named optional paramter random to the function random.shuffle is the function based on which the sorting occurs. random.shuffle modifies the list passed into random.shuffle in place, hence why you call join on the list and not the result of the call to random.shuffle.
>>> wordList = list(ma["vals"][0])) #"balloons"
>>> random.shuffle(wordList,random=random.random)
>>> ''.join(wordList)
'oboanlls'

Splitting a python list into multiple lists

for example, if i have a list like:
one = [1,2,3]
what function or method can i use to split each element into their own separate list like:
one = [1]
RANDOM_DYNAMIC_NAME = [2]
RANDOM_DYNAMIC_NAME_AGAIN = [3]
and at any given time, the unsplit list called one may have more than 1 element, its dynamic, and this algorithm is needed for a hangman game i am coding as self-given homework.
the algorithm is needed to complete this example purpose:
pick a word: mississippi
guess a letter: s
['_','_','s','s','_','s','s','_','_','_','_']
Here is my code:
http://pastebin.com/gcCZv67D
Looking at your code, if the part you're trying to solve is the comments in lines 24-26, you definitely don't need dynamically-created variables for that at all, and in fact I can't even imagine how they could help you.
You've got this:
enum = [i for i,x in enumerate(letterlist) if x == word]
The names of your variables are very confusing—something called word is the guessed letter, while you've got a different variable letterguess that's something else, and then a variable called letter that's the whole word… But I think I get what you're aiming for.
enum is a list of all of the indices of word within letterlist. For example, if letterlist is 'letter' and word is t, it will be [2, 3].
Then you do this:
bracketstrip = (str(w) for w in enum)
So now bracketstrip is ['2', '3']. I'm not sure why you want that.
z = int(''.join(bracketstrip))
And ''.join(bracketstrip) is '23', so z is 23.
letterguess[z] = word
And now you get an IndexError, because you're trying to set letterguess[23] instead of setting letterguess[2] and letterguess[3].
Here's what I think you want to replace that with:
enum = [i for i,x in enumerate(letterlist) if x == word]
for i in enum:
letterguess[i] = word
A few hints about some other parts of your code:
You've got a few places where you do things like this:
letterlist = []
for eachcharacter in letter:
letterlist.append(eachcharacter)
This is the same as letterlist = list(letter). But really, you don't need that list at all. The only thing you do with that is for i, x in enumerate(letterlist), and you could have done the exact same thing with letter in the first place. You're generally making things much harder for yourself than you have to. Make sure you actually understand why you've written each line of code.
"Because I couldn't get it to work any other way" isn't a reason—what were you trying to get to work? Why did you think you needed a list of letters? Nobody can keep all of those decisions in their head at once. The more skill you have, the more of your code will be so obvious to you that it doesn't need comments, but you'll never get to the point where you don't need any. When you're just starting out, every time you figure out how to do something, add a comment reminding yourself what you were trying to do, and why it works. You can always remove comments later; you can never get back comments that you didn't write.
for question one ,just list comprehension is good . it will return each element as a separate list
[ [x,] for x in one ]
As for a literal answer to your question, here's how you do it, though I can't immagine why you would want to to this. Generally, dynamic variable names are poor design. You probably just want a single list, or list of lists.
import random
for x in one:
name = 'x' + str(random.getrandbits(10))
globals()[name] = [x]

Categories