I am writing simple python code:
Question:
Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
Solution I worked:
def match_ends(words):
for items in words:
count = 0
los = len(items)
first_char= items[0]
last_char= items[los-1]
if los >=2 and first_char is last_char:
count = count+1
else:
count = count
print count
return
def main():
print 'match_ends'
match_ends(['aba', 'xyz', 'aa', 'x', 'bbb'])
I keep on Getting answer as 1 all the time, I think it is not looping entirely. Where is the error
another more concise way to do this is just:
sum(1 for s in words if len(s) > 1 and s[0] == s[-1])
I would use the == operator to compare the characters instead of the is keyword. Also you can use the [-1] index to slice from the back to get the last character instead of essentially doing [len-1]. You are also resetting the count to 0 at the beginning of each loop (also count is already a function name, try to avoid naming a variable with the same name)
That being said, here is the same idea with a few changes for readability and fixes for the above.
def matches(words):
total = 0
for word in words:
if (len(word) > 1) and (word[0] == word[-1]):
total += 1
return total
>>> matches(['aba', 'xyz', 'aa', 'x', 'bbb'])
3
The reason is that you need to place count = 0 before the line for items in words:
Related
I have this function to check if a string contains three or more lowercase letters.
def lowerCaseValid(word):
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
i = 0
flag = 0
while i <= len(word):
j = 0
while j <= len(lowCharList):
if lowCharList[j] == word[i]:
flag += 1
j = 0
else:
j += 1
i += 1
if flag >= 3:
return True
In simple terms, I pass in a string (word) and create a list of acceptable characters (lowCharList).
Then, I set up a nested while loop that checks word[i] at every index of lowCharList, until it finds a match.
Then it resets lowCharList counter and adds 1 to flag, and moves on to word[i+1].
If it doesn't find a match by the time it reaches z, then it moves onto word[i+1] anyways.
For some reason, why I try my sample input in my main function.
def main():
word = 'corRe!33'
print(lowerCaseValid(word))
I get this error:
in lowerCaseValid
if lowCharList[j] == word[i]:
IndexError: list index out of range
Why is it throwing this error? Thank you.
using python's in operator is easier...
def lowerCaseValid(word):
cnt = 0
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
chars = lowCharList.pop ()
for ch in word:
if ch in chars:
cnt += 1
return cnt >= 3
or with using sets just 2 lines of code
def lowerCaseValid(word):
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
return len(set(lowCharList.pop()) & set(word)) >=3
or one liner with map and lambda
def lowerCaseValid(word):
return len(list(map(lambda x: x.islower, list(word)))) >=3
Another alternative approach using a list comprehension and string.ascii_lowercase instead of redefining the lowercase letters:
from string import ascii_lowercase
def lowerCaseValid(word):
return sum[x in ascii_lowercase for x in word] >= 3
How this works is that the list comprehension goes through each letter in word. The x in ascii_lowercase will return a boolean value of either True (1) or False (0), then sum up the Trues
Change
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
to
lowCharList = list('abcdefghijklmnopqrstuvwxyz')
I believe this should help, since you have a list containing only 1 item, whereas this way, you create a list with 24 items (all different letters).
As heemayl pointed out in the comments, lowCharList is 1 element long! Now you have 2 options: make lowCharList an actual list (lowCharList = list ("abcd...")), or keep lowCharList a string, which will work just fine (remove the brackets in the definition.
Might I suggest another method: checking if str.islower count adds up to >=3. So:
lower_count = 0
for letter in word:
if letter.islower(): lower_count += 1
if lower_count >= 3: return True
Also, as suggested in the comments:
return len ([letter for letter in word if letter.islower()]) >= 3
would work (better than my answer, which is just the expanded form of it)
Im writing a program to try to calculate how many times the most repeated word in a list occurs. I keep getting an error that says: index error. Even though when I print the list of my word_list, it shows there are 108 elements. Could someone point me in the right direction as to where my error is?
length = len(word_list)
num = 0
print(length)
while num <= length:
ele = word_list[num]
if ele in wordDict:
wordDict[ele] = wordDict[ele] +1
repeat = repeat + 1
if repeat > highestRepeat:
highestRepeat = repeat
else:
wordDict[ele] = 1
repeat = 1
num = num+1
List indexing goes from 0 to length-1.
In your while loop, you've told the num to go from 0 to length. That's why you have an index error.
Simply change num <= length to num < length. That should fix your code for you.
As an aside, there are much better ways to do this particular task. A simple two liner:
from collections import Counter
print(Counter(word_list).most_common(1))
Counter will calculate the frequencies of each element in your list for you, and most_common(1) will return the element with the highest frequency in your list.
Just to mention that there is a more compact solution to your problem:
word_list =['this' ,'is', 'a', 'test', 'is']
for word in set(word_list):
print word, ": ", word_list.count(word)
I am writing a function which should count the numbers in an inputted phrase. That phrase gets stored as a tuple and the while loop should count the number of vowels. So far I have gotten this.
def whilephrase():
vowels=['A','a','E','e','I','i','O','o','U','u']
print('Please give me a phrase')
inputphrase=input()
inputphrase=tuple(inputphrase)
i=0
while True:
if vowels in inputphrase:
i=i+1
else:
print(i)
But this just prints out an endless loop of zeros.
You need to iterate over your inputphrase:
for character in inputphrase:
if character in vowels:
i = i + 1
print(i)
But there is, of course, an easier way:
def count_vowels(string):
return sum(1 for c in string if c.lower() in "aeiou")
edit: Using a while loop (although I'm not sure why you want specifically that):
index = 0
i = 0
while index < len(inputphrase):
if inputphrase[index] in vowels:
i += 1
index += 1
print(i)
print len([i for i in inputphrase if i in vowels])
you can also use collections
from collections import Counter
sum([Counter(inputphrase)[i] for i in vowels])
I'm trying to create a function where you can put in a phrase such as "ana" in the word "banana", and count how many times it finds the phrase in the word. I can't find the error I'm making for some of my test units not to work.
def test(actual, expected):
""" Compare the actual to the expected value,
and print a suitable message.
"""
import sys
linenum = sys._getframe(1).f_lineno # get the caller's line number.
if (expected == actual):
msg = "Test on line {0} passed.".format(linenum)
else:
msg = ("Test on line {0} failed. Expected '{1}', but got '{2}'.".format(linenum, expected, actual))
print(msg)
def count(phrase, word):
count1 = 0
num_phrase = len(phrase)
num_letters = len(word)
for i in range(num_letters):
for x in word[i:i+num_phrase]:
if phrase in word:
count1 += 1
else:
continue
return count1
def test_suite():
test(count('is', 'Mississippi'), 2)
test(count('an', 'banana'), 2)
test(count('ana', 'banana'), 2)
test(count('nana', 'banana'), 1)
test(count('nanan', 'banana'), 0)
test(count('aaa', 'aaaaaa'), 4)
test_suite()
Changing your count function to the following passes the tests:
def count(phrase, word):
count1 = 0
num_phrase = len(phrase)
num_letters = len(word)
for i in range(num_letters):
if word[i:i+num_phrase] == phrase:
count1 += 1
return count1
Use str.count(substring). This will return how many times the substring occurs in the full string (str).
Here is an interactive session showing how it works:
>>> 'Mississippi'.count('is')
2
>>> 'banana'.count('an')
2
>>> 'banana'.count('ana')
1
>>> 'banana'.count('nana')
1
>>> 'banana'.count('nanan')
0
>>> 'aaaaaa'.count('aaa')
2
>>>
As you can see, the function is non-overlapping. If you need overlapping behaviour, look here: string count with overlapping occurrences
You're using the iteration wrong, so:
for i in range(num_letters): #This will go from 1, 2, ---> len(word)
for x in word[i:i+num_phrase]:
#This will give you the letters starting from word[i] to [i_num_phrase]
#but one by one, so : for i in 'dada': will give you 'd' 'a' 'd' 'a'
if phrase in word: #This condition doesnt make sense in your problem,
#if it's true it will hold true trough all the
#iteration and count will be
#len(word) * num_phrase,
#and if it's false it will return 0
count1 += 1
else:
continue
I guess, str.count(substring) is wrong solution, because it doesn't count overlapping substrings and test suite fails.
There is also builtin str.find method, which could be helpful for the task.
Another way :
def count(sequence,item) :
count = 0
for x in sequence :
if x == item :
count = count+1
return count
A basic question rais this times.
when u see a string like "isisisisisi" howmany "isi" do u count?
at first state you see the string "isi s isi s isi" and return 3 as count.
at the second state you see the string "isisisisisi" and counts the "i" tow times per phrase like this "isi isi isi isi isi".
In other word second 'i' is last character of first 'isi' and first character of second 'isi'.
so you have to return 5 as count.
for first state simply can use:
>>> string = "isisisisisi"
>>> string.count("isi")
3
and for second state you have to recognize the "phrase"+"anything"+"phrase" in the search keyword.
the below function can do it:
def find_iterate(Str):
i = 1
cnt = 0
while Str[i-1] == Str[-i] and i < len(Str)/2:
i += 1
cnt += 1
return Str[0:cnt+1]
Now you have many choice to count the search keyword in the string.
for example I do such below:
if __name__ == "__main__":
search_keyword = "isi"
String = "isisisisisi"
itterated_part = find_iterate(search_keyword)
c = 0
while search_keyword in String:
c += String.count(search_keyword)
String = String.replace(search_keyword, itterated_part)
print c
I do not know if a better way be in python.but I tried to do this with help of Regular Expressions but found no way.
I am trying to count the number of times 'e' appears in a word.
def has_no_e(word): #counts 'e's in a word
letters = len(word)
count = 0
while letters >= 0:
if word[letters-1] == 'e':
count = count + 1
letters = letters - 1
print count
It seems to work fine except when the word ends with an 'e'. It will count that 'e' twice. I have no idea why. Any help?
I know my code may be sloppy, I'm a beginner! I'm just trying to figure out the logic behind what's happening.
>>> word = 'eeeooooohoooooeee'
>>> word.count('e')
6
Why not this?
As others mention, you can implement the test with a simple word.count('e'). Unless you're doing this as a simple exercise, this is far better than trying to reinvent the wheel.
The problem with your code is that it counts the last character twice because you are testing index -1 at the end, which in Python returns the last character in the string. Fix it by changing while letters >= 0 to while letters > 0.
There are other ways you can tidy up your code (assuming this is an exercise in learning):
Python provides a nice way of iterating over a string using a for loop. This is far more concise and easier to read than using a while loop and maintaining your own counter variable. As you've already seen here, adding complexity results in bugs. Keep it simple.
Most languages provide a += operator, which for integers adds the amount to a variable. It's more concise than count = count + 1.
Use a parameter to define which character you're counting to make it more flexible. Define a default argument for using char='e' in the parameter list when you have an obvious default.
Choose a more appropriate name for the function. The name has_no_e() makes the reader think the code checks to see if the code has no e, but what it actually does is counts the occurrences of e.
Putting this all together we get:
def count_letter(word, char='e'):
count = 0
for c in word:
if c == char:
count += 1
return count
Some tests:
>>> count_letter('tee')
2
>>> count_letter('tee', 't')
1
>>> count_letter('tee', 'f')
0
>>> count_letter('wh' + 'e'*100)
100
Why not simply
def has_no_e(word):
return sum(1 for letter in word if letter=="e")
The problem is that the last value of 'letters' in your iteration is '0', and when this happens you look at:
word[letters-1]
meaning, you look at word[-1], which in python means "last letter of the word".
so you're actually counting correctly, and adding a "bonus" one if the last letter is 'e'.
It will count it twice when ending with an e because you decrement letters one time too many (because you loop while letters >= 0 and you should be looping while letters > 0). When letters reaches zero you check word[letters-1] == word[-1] which corresponds to the last character in the word.
Many of these suggested solutions will work fine.
Know that, in Python, list[-1] will return the last element of the list.
So, in your original code, when you were referencing word[letters-1] in a while loop constrained by letters >= 0, you would count the 'e' on the end of the word twice (once when letters was the length-1 and a second time when letters was 0).
For example, if my word was "Pete" your code trace would look like this (if you printed out word[letter] each loop.
e (for word[3])
t (for word[2])
e (for word[1])
P (for word[0])
e (for word[-1])
Hope this helps to clear things up and to reveal an interesting little quirk about Python.
#marcog makes some excellent points;
in the meantime, you can do simple debugging by inserting print statements -
def has_no_e(word):
letters = len(word)
count = 0
while letters >= 0:
ch = word[letters-1] # what is it looking at?
if ch == 'e':
count = count + 1
print('{0} <-'.format(ch))
else:
print('{0}'.format(ch))
letters = letters - 1
print count
then
has_no_e('tease')
returns
e <-
s
a
e <-
t
e <-
3
from which you can see that
you are going through the string in reverse order
it is correctly recognizing e's
you are 'wrapping around' to the end of the string - hence the extra e if your string ends in one
If what you really want is 'has_no_e' then the following may be more appropriate than counting 'e's and then later checking for zero,
def has_no_e(word):
return 'e' not in word
>>> has_no_e('Adrian')
True
>>> has_no_e('test')
False
>>> has_no_e('NYSE')
True
If you want to check there are no 'E's either,
def has_no_e(word):
return 'e' not in word.lower()
>>> has_no_e('NYSE')
False
You don't have to use a while-loop. Strings can be used for-loops in Python.
def has_no_e(word):
count = 0
for letter in word:
if letter == "e":
count += 1
print count
or something simpler:
def has_no_e(word):
return sum(1 for letter in word if letter=="e")