List modification doesn't change list - python

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.

Related

How do I check if a sequence of characters exists in a list?

How do I check if a sequence of characters exists in a list?
I have a string with some characters that have sequences that reoccur. I know that strings are immutable so I turn the string into the list. However, I'm not sure how to iterate through the list, find the occurrence and change the first letter of the occurrence.
message: DDMCAXQVEKGYBNDDMZUH
Occurence is: DDM
list: ['D', 'D', 'M', 'C', 'A', 'X', 'Q', 'V', 'E', 'K', 'G', 'Y', 'B', 'N', 'D', 'D', 'M', 'Z', 'U', 'H']
What I have currently is simply turning the message into the list. I've tried different ways, which were unsuccessfully that's what I didn't post it. Not really asking you to write the code but at the least explain how to achieve this.
It's a lot easier to check if a string exists in another string since you can simply use the in operator:
if 'DDM' in message:
# do something
But since your goal is to change the first letter of the occurrence, you can use the str.index method to obtain the index of the occurrence and then assemble a new string with slices of the current string and the new letter:
try:
i = message.index('DDM')
message = message[:i] + new_letter + message[i + 1:]
except ValueError:
raise RuntimeError("Sequence 'DDM' not found in message.")
You can use re.sub():
import re
s = 'DDMCAXQVEKGYBNDDMZUH'
re.sub(r'DDM', '$DM', s)
# $DMCAXQVEKGYBN$DMZUH
A simple solution with a for-loop would be:
msg = 'DDMCAXQVEKGYBNDDMZUH'
occ = 'DDM'
for i in range(len(msg)):
if msg[i:i+len(occ)] == occ:
msg = msg[:i] + 'x' + msg[i+1:]
resulting in xDMCAXQVEKGYBNxDMZUH
This also works with overlapping substrings. For example:
msg = 'AAABAA'
occ = 'AA'
will give xxABxA
The simplest way would be using string replace() function.
string.replace(s, old, new[, maxreplace])
Return a copy of string s with all occurrences of substring old replaced by new. If the optional argument maxreplace is given, the first maxreplace occurrences are replaced.
message = "DDMCAXQVEKGYBNDDMZUH"
print message.replace("DDM", "ABC", 1)
Replace function would replace the first occurrence of DDM in the message string.
output: ABCCAXQVEKGYBNDDMZUH
If I carefully read your question you want to search the first occurrence of DDM in your message and replace the first character of it. In that case use below:
message = "DDMCAXQVEKGYBNDDMZUH"
print message.replace("DDM", "ADM", 1)
output: ADMCAXQVEKGYBNDDMZUH

Use the method is_vowel

Write a value returning method, is vowel that returns true if a given characters is vowel otherwise returns false. Write a program that prompts the user to input a sequence of characters and outputs the number of vowels. Please help me to run this problem and what is the exact code
You can use char in "aeiouAEIOU" to determine if a character is a vowel, and use a list comprehension to produce a list containing only vowels, and find the number of vowels in the input string by finding the length of this list.
string=raw_input()
numOfVowels=len([char for char in string if char in "aeiouAEIOU"])
print(numOfVowels)
Input:
abcdefghijklmnopqrstuvwxyz
Output:
5
make a list of vowel letter to comapre letters in input that user enters:
vowel = ['a', 'e', 'i', 'o', 'u']
user_ask = input("enter a string to count the vowel:\t").casefold()
by using casefold method, you do not need to worry about upper and lowercase letters.
count = 0
new_vowel = []
for i in user_ask:
if i in vowel:
count += 1
new_vowel.append(i)
print("number of vowels\n", count)
you can use counter if you want to print them in a key value pairs, i.e. as a dictionary.
from collections import Counter
dict(Counter(new_vowel))
Output
enter a string to count the vowel: I am trying to learn
number of vowels :
6
and the dictionary form is:
{'i': 2, 'a': 2, 'o': 1, 'e': 1}

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.

Longest repeating substring using for-loops and if-statements

I'm in an introductory level programming class that teaches python. I was introduced to a longest repeating substring problem for a project and I can't seem to crack it. I've looked on here for a solution, but I haven't learned suffix trees yet so I wouldn't be able to use them. So far, I've gotten here:
msg = "kalhfdlakdhfklajdf" (anything)
for i in range(len(msg)):
if msg[i] == msg[i + 1]:
reps.append(msg[i])
What this does is scan my string, msg, and check to see if the counter matches the next character in sequence. If the characters match, it appends msg[i] to the list "reps". My problem is that:
a) The function I created always appends one less than repetition amount, and
b) my function program always crashes due to msg[i+1] going out of bounds once it reaches the last spot on the list.
In essence, I want my program to find repeats, append them to a list where the highest repeating character is counted and returned to the user.
You need to use len(msg)-1 as your range but your condition will omit one character with your condition, and for getting ride of that you can add another condition to your code that check the preceding characters too :
with you'r condition you'll have 8 h in reps till there is 9 in msg:
>>> msg = "kalhfdlakdhhhhhhhhhfklajdf"
>>> reps = []
>>> for i in range(len(msg)-1):
... if msg[i] == msg[i + 1]:
... reps.append(msg[i])
...
>>> reps
['h', 'h', 'h', 'h', 'h', 'h', 'h', 'h']
And with another condition :
>>> reps=[]
>>> for i in range(len(msg)-1):
... if msg[i] == msg[i + 1] or msg[i] == msg[i - 1]:
... reps.append(msg[i])
...
>>> reps
['h', 'h', 'h', 'h', 'h', 'h', 'h', 'h', 'h']
For the groupby answer I alluded to on #Kasra's excellent response:
from itertools import groupby
msg = "kalhfdlakdhhhhhhhhhfklajdf"
maxcount = 0
for substring in groupby(msg):
lett, count = substring[0], len(list(substring[1]))
if count > maxlen:
maxcountlett = lett
maxcount = count
result = [maxcountlett] * maxlen
But note that this only works for substrings of length 1. msg = 'hahahaha' should give ['ha', 'ha', 'ha', 'ha'] by my understanding.
a) Think about what is happening when it makes the first match.
For example, given abcdeeef it sees that msg[4] matches msg[5]. It then goes and appends msg[4] to reps. Then msg[5] matches msg[6] and it appends msg[5] to reps. However, msg[6] does not match msg[7] so it does not append msg[6]. You are one short.
In order to fix this you need to append one extra for each string of matches. A good way to do this is to check if the character you're currently matching already exists in reps. If it does only append the current one. If it does not append it twice.
if msg[i] == msg[i+1]
if msg[i] in reps
reps.append(msg[i])
else
reps.append(msg[i])
reps.append(msg[i])
b) You need to ensure that you do not exceed your boundaries. This can be accomplished by taking 1 off of your range.
for i in (range(len(msg)-1))

Comparing and printing elements in nested loops

The program identifies if one of the elements in the string word is a consonant by looping though the word string, and then for each iteration though the word string, iterating though the consonants list and comparing if the current element in word string equals to the current element of consonant list.
If yes, the current element of the word string is a consonant and the consonant gets printed (not the index of the consonant, but the actual consonant, for e.g. "d".)
The problem is, I get this instead:
1
1
What am I doing wrong? Shouldn't the nested loops work so that the below loop iterates every element for each element in the above loop? That is, each index above makes the below loop iterate though each index?
That's the program:
word = "Hello"
consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z']
for character in range(len(word)):
for char in range(len(consonants)):
if consonants[char] == word[character]:
consonant = word[character]
print consonant
You are misreading the output. The character is the letter L lowercase, not the number 1.
In other words, your code is working as designed. The captital letter H is not in your consonants list, but the two lowercase letters l in Hello are.
Note that it'd be much more efficient to use a set for consonants here; you'd not have to loop over that whole list and just use in to test for membership. That works with lists too, but is much more efficient with a set. If you lowercase the word value you'd also be able to match the H.
Last but not least, you can loop over the word string directly rather than use range(len(word)) then use the generated index:
word = "Hello"
consonants = set('bcdfghjklmnpqrstvwxz')
for character in word.lower():
if character in consonants:
print character
Demo:
>>> word = "Hello"
>>> consonants = set('bcdfghjklmnpqrstvwxz')
>>> for character in word.lower():
... if character in consonants:
... print character
...
h
l
l

Categories

Resources