Python: Appending to a list - python

I'm working on a definition tester (you enter in words, their part of speeches, and synonyms for each, and it tests you on them). Problem I have is with the part that gets the word:
def get_word(): # this is in another function, that's why it is indented
import easygui as eg
word_info = eg.multenterbox(msg = 'Enter in the following information about each word.'
, title = 'Definition Tester'
, fields = ['Word: ', 'Part of Speech: ', 'Synonyms (separated by spaces): ']
, values = []
)
return word_info
for i in range(n):
my_list = get_word()
print my_list # for testing
word, pOS, synonyms = my_list[0], my_list[1], my_list[2]
word = word.capitalize()
synonyms = synonyms.split(', ')
words_list += word
print word # for testing
test_dict[word] = [pOS, synonyms]
print words_list # for testing
However, words_list ends up being the word(s) after the list(word) function is applied to them--- I'm not sure why.
For example: if the only word was 'word', words_list turns out to be ['w', 'o', 'r', 'd']. If there were two words ('dog', 'cat'), words_list turns out to be ['d', 'o', 'g', 'c', 'a', 't'].
Here is my input (into get_word()): Word: 'myword', Part of Speech: 'n', Synonyms: 'synonym, definition'.
This is the output I get:
['myword', 'n', 'synonym, definition']
Myword
['M', 'y', 'w', 'o', 'r', 'd'] # Why does this happen?
This is the only thing wrong with my program... If I could get some input on how to fix this and what is wrong, it would be much appreciated. Thanks!

It's because of this line:
words_list += word
+= on a list is for adding all the elements in another list. As it happens, Python strings also function like lists of characters, so you are adding each character to the list as its own element.
You want this:
words_list.append(word)
which is for adding a single element to the end.

After messing around with it, I figured out the problem myself, so I thought I should put it here for anyone who has something similar:
Instead of doing words_list += word, it should be: words_list.append(word).
Or, which is what I did, you can do: words_list += [word]. Now, word is a list object, so it will add onto the previous list.

Related

List modification doesn't change list

I'm trying to reverse a string, so I converted the string into a list and was trying to send the last element to the front, 2nd to last element to the 2nd space, etc.
word = input("Enter a word: ")
word = list(word)
count = 0
while count < len(word):
word.insert(count, word.pop())
count = count + 1
print(word)
It just returns the original string in list form, even though I'm saving the last letter and inserting it before popping it off of the string? Does word.pop() not capture the last letter of a string before deleting it or am I overlooking something?
Well the simplest way to do what you are trying is to slice the string in reverse order, this does not even require changing into a list:
word = input("Enter a word: ")
return word[::-1]
Here's an experiment:
>>> word = list('python')
>>> word.insert(0, word[-1])
>>> word
['n', 'p', 'y', 't', 'h', 'o', 'n']
>>> word.remove(word[-1])
>>> word
['p', 'y', 't', 'h', 'o', 'n']
Wait, what?!
>>> help(word.remove)
Help on built-in function remove:
remove(value, /) method of builtins.list instance
Remove first occurrence of value.
Raises ValueError if the value is not present.
Remove first occurrence of value.
So, you inserted word[-1] at the beginning of the list, and then word.remove immediately removes the first occurrence of word[-1], which is now at the beginning of the list, you've just inserted it there!
You're setting the variables inside the while-loop to the same value. Also, use list.pop to remove the element from the list. For example:
word = input("Enter a word: ")
word = list(word)
count = 0
while count < len(word):
word.insert(count, word.pop())
count = count + 1
print(word)
Prints:
Enter a word: book
['k', 'o', 'o', 'b']
Here is the docstring for list.remove:
>>> help(list.remove)
Help on method_descriptor:
remove(self, value, /)
Remove first occurrence of value.
Raises ValueError if the value is not present.
>>>
As you can see, list.remove removes the first occurrence of the given value from the list. All your backwards function does right now is take the last character of the word, add it to the front and then immediately remove it from the front again. You do this once for every character in the word, the net result being no change.

different result in print command because of in python 3

i am new to python and am still learning. I wanted to know what is the difference between these two commands and why do they output different results.
Without white space
hello = []
for letter in 'word':
hello.append(letter)
print(hello)
Output
['w', 'o', 'r', 'd']
With White space
hello = []
for letter in 'word':
hello.append(letter)
print(hello)
output
['w']
['w', 'o']
['w', 'o', 'r']
['w', 'o', 'r', 'd']
Python interprets the code based on tabbed whitespace (really it is 4 spaces).
In the first example, you append all the letters of the word into a list, and then you print the contents of the list. Here, you are only printing the contents of the list after the loop is executed.
lst = []
for letter in 'word':
lst.append(letter)
print(lst)
In the second example, you append the letters of the word into a list, but you also print the contents of the list within the loop. So every time a letter is added, you print the contents of what's inside that list. Note: the difference here is that the print statement is within the loop, and not outside of it.
lst = []
for letter in 'word':
lst.append(letter)
print(lst)

Trouble splitting text without using split()

splitText(text) where text is a string and return the list of the words by splitting the string text.
See example below:
sampleText = "As Python's creator, I'd like to say a few words about its origins.”
splitText(sampleText)
['As', 'Python', 's', 'creator', 'I', 'd', 'like', 'to', 'say', 'a', 'few', 'words', 'about', 'its', 'origins']
You must NOT use the method split() from the str type, however other methods >from the class are allowed. You must not use python library such as string.py.
This is my code:
def split(text):
final_lst = ""
length = len(text)
for x in range(length):
if text[x].isalpha() == True:
final_lst = final_lst + text[x]
else:
final_lst = final_lst + ", "
final_len = len(final_lst)
for a in range(final_len):
if final_lst[:a] == " " or final_lst[:a] == "":
final_lst = "'" + final_lst[a]
if final_lst[a:] == " " or final_lst[a:] == ", ":
final_lst = final_lst[a] + "'"
elif final_lst[:a].isalpha() or final_lst[a:].isalpha():
final_lst[a]
print(final_lst)
split(sampleText)
When I run it I get this:
'A
I've tried lots of things to try and solve.
First of all, your function name is wrong. You have split(text) and the exercise specifically calls for splitText(text). If your class is graded automatically, for example by a program that just loads your code and tries to run splitText(), you'll fail.
Next, this would be a good time for you to learn that a string is an iterable object in Python. You don't have to use an index - just iterate through the characters directly.
for ch in text:
Next, as #Evert pointed out, you are trying to build a list, not a string. So use the correct Python syntax:
final_list = []
Next, let's think about how you can process one character at a time and get this done. When you see a character, you can determine whether it is, or is not, an alphabetic character. You need one more piece of information: what were you doing before?
If you are in a "word", and you get "more word", you can just append it.
If you are in a "word", and you get "not a word", you have reached the end of the word and should add it to your list.
If you are in "not a word", and you get "not a word", you can just ignore it.
If you are in "not a word", and you get "word", that's the start of a new word.
Now, how can you tell whether you are in a word or not? Simple. Keep a word variable.
def splitText(text):
"""Split text on any non-alphabetic character, return list of words."""
final_list = []
word = ''
for ch in text:
if word: # Empty string is false!
if ch.isalpha():
word += ch
else:
final_list.append(word)
word = ''
else:
if ch.isalpha():
word += ch
else:
# still not alpha.
pass
# Handle end-of-text with word still going
if word:
final_list.append(word)
return final_list
sampleText = "As Python's creator, I'd like to say a few words about its origins."
print(splitText(sampleText))
Output is:
['As', 'Python', 's', 'creator', 'I', 'd', 'like', 'to', 'say', 'a', 'few', 'words', 'about', 'its', 'origins']
Next, if you sit and stare at it for a while you'll realize that you can combine some of the cases. It boils down nicely- try turning it inside out by moving the outer if to the inside, and see what you get.
To me, it looks like you are complicating things too much, basically all you need to do is to go through the text char by char, and combining them to words, once you find empty space you separate it and add it to the result array. After you run out of text you just return the array.
def splittext(text):
result = []
word = ""
for i in text:
if i != " ":
word += i
else:
result.append(word)
word = ""
result.append(word)
return result
This should work:
smapleText = 'As Python\'s creator, I\'d like to say a few words about its origins.'
def split(text):
result =[]
temp=""
length = len(text)
for x in range(length):
if text[x].isalpha():
temp = temp+text[x]
else:
result.append(temp)
temp=""
print result
split(smapleText)
Can you cheat with regular expressions?
import re
sampleText = "As Python's creator, I'd like to say a few words about its origins."
result = re.findall(r'\w+', sampleText)
>>> result
['As', 'Python', 's', 'creator', 'I', 'd', 'like', 'to', 'say', 'a', 'few', 'words', 'about', 'its', 'origins']
def stringSplitter(string):
words = []
current_word = ""
for x in range(len(string)):
if string[x] == " ":
words.append(current_word)
current_word = ""
else:
current_word += string[x]
return words

Eliminating last element in array

So I am working on a small hangman text based game.
The problem I am currently dealing with is calling random words from my text file. Each word has one additional character for a new line (\n).
For instance, running through my function that separates a string's letters into individual elements I get something to the effect of:
from text file: guess
answer = arrange_word(guess)
>>>>> ['g', 'u', 'e', 's', 's', '\n']
however, when joining the array back together the following is shown:
print ''.join(arrange_word)
>>>>> guess
as you can see, it is a bit difficult to guess an element that does not show up.
For clarity here is my function for arrange_word:
def arrange_word(word):
##########
# This collects the mystery word and breaks it into an array of
# individual letters.
##########
word_length = len(word)
break_up = ["" for x in range(word_length)]
for i in range(0, word_length):
break_up[i] = word[i]
return break_up
What I am stuck on is that when trying to guess letters, the \n is impossible to guess. The win condition of my game is based on the guess being identical to the answer word. However the \n keeps that from working because they are of different length.
These answer arrays are of different length as well, since I am just pulling random lines from a text file of ~1000 words. After hours of searching I cannot seem to find out how to drop the last element of an array.
For this line here:
word_length = len(word)
Before you take the length, what you can do is this first:
word = word.strip()
Explanation:
strip removes leading and trailing whitespace.
>>> s = "bob\n"
>>> s
'bob\n'
>>> s.strip()
'bob'
With all this in mind, you don't need the rest of this code anymore:
word_length = len(word)
break_up = ["" for x in range(word_length)]
for i in range(0, word_length):
break_up[i] = word[i]
Applying the strip will give you your word without the whitespace character, then all you want to do after this to have a list of characters, is simply:
>>> s = "bob"
>>> list(s)
['b', 'o', 'b']
So your method can now simply be:
def arrange_word(word):
return list(word.strip())
Demo:
arrange_word("guess")
Output:
['g', 'u', 'e', 's', 's']
All these answers are fine for specifically stripping whitespace characters from a string, but more generally, Python lists implement standard stack/queue operations, and you can make your word into a list just by calling the list() constructor without needing to write your own function:
In [38]: letters = list('guess\n')
letters.pop()
letters
Out[38]: ['g', 'u', 'e', 's', 's']
Use List slicing
arr = [1,2,3,4]
print(arr[:-1:])
Array slicing syntax is [startindex:endindex:offset(2, means each 2 element)] So in your case you could. Which mean start at the begging of the list, to the last element -1 for every 1 element in the list.
return break_up[:-1:]
you can access last element by -1 index like:
guess[-1]
and you can delte it by:
del guess[-1]
Just strip the word:
word = 'guess\n'
word = word.strip() ## 'guess' without new line character, or spaces
Maybe first line of your arrange_word function should be
word = word.strip()
to remove all leading/trailing whitespace characters.

List out of range

im trying to do letter sorting according to this example :
Input:
people enjoy programming
Output:
[(set(['e', 'o']), set(['l']), set(['p'])),
(set(['e', 'o']), set(['j']), set(['n', 'y'])),
(set(['o', 'a', 'i']), set(['g', 'm']), set(['p', 'r', 'n']))]
So here is my code :
lista=[[[0],[0],[0]],[[0],[0],[0]],[[0],[0],[0]]]
x=raw_input('please enter 3 words: ')
words=x.split()
if len(words)!=3:
print('error!!! enter 3 words ')
else:
i=0
c=0
while i<3:
for m in range(len(words[i])):
if words[i][m] in ['a','e','i','o','u']:
lista.insert([i][0][c],words[i][m])
lista.insert([i][0][-1],0)
c=c+1
elif words[i][m] in ['b','c','d','f','g','h','j','k','l','m']:
lista.insert([i][1][c],words[i][m])
lista.insert([i][1][-1],0)
c=c+1
else:
lista.insert([i][2][c],words[i][m])
lista.insert([i][2][-1],0)
c=c+1
i=i+1
lista=(set(lista[1][1],lista[1][2],lista[1][3],lista[2][1],lista[2][2],lista[2][3],lista[3][1],lista[3][2],lista[3][3]))
lista=(tuple(lista[1],lista[2],lista[3]))
print lista
And when i try to run it i get this error :
Traceback (most recent call last): File "C:/Python27/ex7.py", line 22, in
lista.insert([i][2][c],words[i][m]) IndexError: list index out of range
Someone see what i did wrong?
I don't think the line lista.insert([i][1][c],words[i][m]) (and the similar lines with other indexes) do what you seem to be intending. Rather than inserting words[i][m] into lista[i][1][c], you're getting an error when trying to evaluate [i][1][c]. That subexpression creates an one element list ([i], then tries to access the value at index 1, which doesn't work.
I think you may want to use something like lista[i][1].append(words[i][m]).
However, it would be much easier if you directly iterated over your lists and strings, rather than using ranges and indexing:
output = []
for word in words:
vowels = set()
consonants1 = set()
consonants2 = set()
for character in word:
if character in "aeiou":
vowels.add(character)
elif character in "bcdfghjklm":
consonants1.add(character)
else:
consonants2.add(character)
output.append([vowels, consonants1, consonants2])
words = []
output = []
desired_output = [(set(['e', 'o']), set(['l']), set(['p'])), (set(['e', 'o']), set(['j']), set(['n', 'y'])),
(set(['o', 'a', 'i']), set(['g', 'm']), set(['p', 'r', 'n']))]
while True:
# words = raw_input('please enter 3 words: ').split()
words = "people enjoy programming".split()
if len(words) != 3:
print('error!!! enter 3 words ')
else:
break
for word in words:
vow = set()
con1 = set()
con2 = set()
for char in word:
if char in "aeiou":
vow.add(char)
elif char in "bcdfghjklm":
con1.add(char)
else:
con2.add(char)
output.append([vow, con1, con2])
print output
print desired_output
Output:
[[set(['e', 'o']), set(['l']), set(['p'])], [set(['e', 'o']), set(['j']), set(['y', 'n'])], [set(['a', 'i', 'o']), set(['m', 'g']), set(['p', 'r', 'n'])]]
[(set(['e', 'o']), set(['l']), set(['p'])), (set(['e', 'o']), set(['j']), set(['y', 'n'])), (set(['a', 'i', 'o']), set(['m', 'g']), set(['p', 'r', 'n']))]
Replace the words = "people enjoy programming".split() for the one above it to make it interactive.
Your use of range and index to access items is very common among anyone who already had a past programming experience(perhaps C++?), in Python most of the things are iterable. You can use a for loop over a list, and it will return each item, you can iterate over a string and it will return each character.

Categories

Resources