# -*- coding:UTF-8 -*-
str= "Green tree"
scr= "e"
cstr= len(str)
n=0
a=0
while n < cstr:
if str[n] == scr:
print(len(scr))
n=n+1
I have to count "e" in -str- string, but when I run this script I get
1
1
1
1
instead of 4.
What's the problem?
First of all, don't use str as a variable name, it will mask the built-in name.
As for counting characters in a string, just use the str.count() method:
>>> s = "Green tree"
>>> s.count("e")
4
If you are just interested in understanding why your current code doesn't work, you are printing 1 four times because you will find four occurrences of 'e', and when an occurrence is found you are printing len(scr) which is always 1.
Instead of printing len(scr) in your if block, you should be incrementing a counter that keeps track of the total number of occurrences found, it looks like you set up a variable a that you aren't using, so the smallest change to your code to get it to work would be the following (however as noted above, str.count() is a better approach):
str= "Green tree"
scr= "e"
cstr= len(str)
n=0
a=0
while n < cstr:
if str[n] == scr:
a+=1
n=n+1
print(a)
Use the count method:
>>> st="Green tree"
>>> st.count('e')
4
If the count method is broken on your Python ;-), you can use a for loop:
st="Green tree"
tgt='e'
i=0
for c in st:
if c==tgt: i+=1
print i
# 4
If you really want a while loop:
idx=0
i=0
while idx<len(st):
if st[idx]==tgt: i+=1
idx+=1
print i
But, this being Python, a more 'Pythonic' approach if your count method broken is to use sum on a generator expression:
>>> sum(1 for c in st if c=='e')
4
scr= "e"
##
print(len(scr))
For why it's doing this, it's doing what you asked, and printing the length of the variable scr, which is always one.
You're best to use the str.count() method as others mentioned, or increment a counter yourself manually.
Related
I am new to Python and I am not sure what is wrong with my syntax or logic here as this seems fairly straightforward. Do I need to split the words into chars?
Count how many words in a list have length 5.
This is what I have so far:
def countWords(lst):
total=0
for word in lst:
if len(word)==5:
total+=1
return total
Update: There are great answers and explanations here, thank you! Unfortunately, I think the activecode is just not working on this site: https://runestone.academy/runestone/books/published/thinkcspy/Lists/Exercises.html: Question 10.
First you have to fix your indentation, and then you probably want to use another name for your sum variable. I've changed it to found below for you.
def countWords(lst):
found = 0
for word in lst:
if len(word) == 5:
found += 1
return found
Then you'll have to call the function, so
countWords(lst)
where lst is the list of words.
First, indentation is very important in Python, also avoid using built-in names like sum, len etc. Also, function name should be in lower case, with words separated by an underscore. here is the multiline solution
def count_words(lst):
word_count = 0
for word in lst:
if len(word) == 5:
word_count += 1
return word_count
and here is the one-liner solution
def count_words(lst):
return len([word for word in lst if len(word) == 5])
the code correct and will provide you, total no of words having a length of 5.
you don't need to count the individual character of a word as len(str) provide the total no of characters inside the word.
to make this solution more scalable and testable for different length words, you can provide length as an option in the functional argument. setting default word length equals to 5 default and check it inside the function. Adding code for it
def countWords(lst,word_length=5):
total=0
for word in lst:
if len(word)==word_length:
total+=1
return total
if you want solution in single line
def countWords(lst, word_length=5):
return sum(1 for word in lst if len(word)==word_length)
you can do this more directly, by using a list comprehension to find all of the words, and counting from there.
def countWords(lst):
return sum([int(len(word) == 5) for word in lst])
This iterates through all of the words, checking the length, and adding up the resulting Booleans: True is , Falseis 0, by definition. Actually, you don't *need* theint` conversion, but some people prefer it for clarity.
You can also achieve the same using a map + lambda to single out the words in the list of length 5.
lst = ["12345", "123", "1234", "abcde", "123", "1234", "abcde"]
def countWords(lst):
return sum(map(lambda word: len(word) == 5, lst))
print(countWords(lst))
outputs:
3
You must remember that in Python, the indentation is important. In your case, since return sum is not indented, it is considered outside of your countWords() function.
The valid code is:
def countWords(lst):
count=0
for word in lst:
if len(word)==5:
count+=1
return count
It seems to be an indentation problem, check your indentation in the Idle (it makes it more obvious).
Since you are new to python, I will show you some cool ways to do this in python style.
return (len([word for word in lst if len(word) == 5]))
# using the filter function
def isWord(word):
return len(word) == 3
#an_iterator = filter(isWord, lst)
return len(list (filter(isWord, lst)))
# using lambda
#an_iterator = filter(lambda word: len(word), lst)
return len(list (filter(lambda word: len(word), lst)))
I am making a program in python that count up the number of letter pairs.
For example ------> 'ddogccatppig' will print 3, 'a' will print 0, 'dogcatpig' will print 0, 'aaaa' will print 3, and 'AAAAAAAAAA' will print 9.
My teacher told me to use a for loop to get the i and i+1 index to compare. I do not know how to do this, and I am really confused. My code:
def count_pairs( word ):
pairs = 0
chars = set(word)
for char in chars:
pairs += word.count(char + char)
return pairs
Please help me!!! Thank you.
The for loop is only to iterate through the appropriate values of i, not directly to do the comparison. You need to start i at 0, and iterate through i+1 being the last index in the string. Work this out on paper.
Alternately, use i-1 and i; then you want to start i-1 at 0, which takes less typing:
for i in range(1, len(word)):
if word[i] == word[i-1]:
...
Even better, don't use the counter at all -- make a list of equality results and count the True values:
return sum([word[i] == word[i-1] for i in range(1, len(word))])
This is a bit of a "dirty trick" using the fact that True evaluates as 1 and False as 0.
If you want to loop over indices instead of the actual characters, you can do:
for i in range(len(word)):
# do something with word[i] and/or word[i+1] or word[i-1]
Converting the string to a set first is counterproductive because it removes the ordering and the duplicates, making the entire problem impossible for two different reasons. :)
Here is an answer:
test = "ddogccatppig"
def count_pairs(test):
counter = 0
for i in range(0,len(test)-1):
if test[i] == test[i+1]
counter+=1
return counter
print(count_pairs(test))
Here you iterate through the length of the string (minus 1 because otherwise you will get an index out of bounds exception). Add to a counter if the letter is the same as the one in front and return it.
This is another (similar) way to get the same answer.
def charPairs(word):
word = list(word)
count = 0
for n in range(0, len(word)-1):
if word[n] == word[n+1]:
count +=1
return count
print(charPairs("ddogccatppig"))
print(charPairs("a"))
print(charPairs("dogcatpig"))
print(charPairs("aaaa"))
print(charPairs("AAAAAAAAAA"))
my_string = "aaabbcccaa"
required_output = "a3b2c3a2"
Please do not provide the code, I would like to try it myself, Please suggest me an approach with which i can get the required output.
As suggested by #ggradnig I've tried the below code.
def count_string(s):
current_char= s[0]
counter =0
result_string = ''
for i in range(len(s)):
if s[i] == current_char:
counter+=1
if s[i] != current_char:
result_string=result_string+current_char+str(counter)
current_char = s[i]
counter = 1
continue
result_string=result_string+current_char+str(counter)
return result_string
given_string=count_string("aabbbccccaa")
print(given_string)
Please suggest changes to improve the above code
Declare a variable for the current character you are counting and a counter variable. Set the "current character" to the first character of the string and the counter to 0. Also, declare an empty result String.
Now iterate over each character of the input String and check if it equals your "current character". If no, append this character to your result String, followed by the current value of the counter. Also, set the counter to 1 after appending and the "current character" to the character you are currently iterating over (i.e. the next character). If the character your currently iterating equals your "current character", increase your counter.
my_string = "aaabbcccaa" required_output= a3b2c3a2
You are counting consecutive characters, if the subsequent character is same, you increment a count variable, if the subsequent char is different, you move on and reinitialize count variable. Append count to the encountered character. When appending integer to a string you will have to typecast. Time complexity is O(n)
Use hashing.. with dictionaries in python. Make the character key and its occurrence a value.. And then traverse the dictionary... and took a empty string and append the both key and its value to the string.
EDIT
Now i think to change my approach instead of using sets under Dictionary and making things complex we can use simple approach. This program is working.
string2=""
string=input()
i=0
while(i<len(string)):
count=1
for j in range(i+1,len(string)):
if string[i]==string[j]:
count+=1
else:
break
string2=string2+string[i]
string2=string2+str(count)
i=i+count
print(string2)
The function groupby() in the module itertools makes this trivial. Read it's documentation where it shows the example (in comments):
>>> [list(g) for k, g in groupby('AAAABBBCCD')]
[['A', 'A', 'A', 'A'], ['B', 'B', 'B'], ['C', 'C'], ['D']]
From here you simply combine the first element of each sublist with the length of that sublist and you have your answer. Some string conversion and joining lists on empty strings necessary but basically a one-liner.
I don't understand why folks recommend the str.count() method. It combines two 'a' runs into one count which isn't desired and once you've broken the string into same letter substrings, len() can do the job.
Please suggest changes to improve the above code
from itertools import groupby
string = 'aaabbcccaa'
def count_string(s):
return ''.join(x[0] + str(len(x)) for x in (list(g) for _, g in groupby(s)))
print(string, '->', count_string(string))
Or if you wish to stay with your current algorithm, I suggest at least the following code cleanup:
def count_string(s):
counter = 0
result_string = ''
current_char = s[0]
for c in s:
if c == current_char:
counter += 1
else:
result_string += current_char + str(counter)
current_char = c
counter = 1
return result_string + current_char + str(counter)
You should use a for loop and string "count" method
and if you want me to post the code also tell me
Python has two method that you might fine useful.
I think python has count method that you could use or there is a length method that you can pass your string to and it out the length of the string.
Recently, I def a function which can compare two words in each wordlist. However, I also found some problems here.
def printcorrectletters():
x=0
for letters in correctanswer:
for letters2 in userinput:
if letters == letters2:
x = x+1
break
return x
In this function, if the correctanswer='HUNTING', and I input 'GHUNTIN', it will show 6 letters are correct. However, I want it compare words' letters 1 by 1. So, it should march 0. For example, 'H' will match first letter of userinput.. and so on.
I also think another function which can solve it by using 'zip'. However, our TA ask me to finish it without things like 'zip'.
If the strings are different lengths, you want to compare each letter of the shorter string:
shortest_length = min(len(correctanswer), len(userinput))
min just gives you the minimum of two or more values. You could code it yourself as:
def min(a, b):
return a if a < b else b
You can index a character in a string, using [index]:
>>> 'Guanfong'[3]
n
So you can loop over all the letter indices:
correct = 0
for index in range(shortest_length):
if correctanswer[index] == userinput[index]:
correct += 1
If you did use zip and sum:
correct = sum(1 for (correct_char, user_char) in zip(correctanswer, userinput)
if correct_char == user_char)
Python provides great facilities for simplifying ideas and for communicating with the computer and programmers (including yourself, tomorrow).
Without zip you can use enumerate() to loop over elements of correctanswer , and get index and element at the same time. Example -
def printcorrectletters():
x=0
for i, letter in enumerate(correctanswer):
if i < len(userinput) and letter == userinput[i]:
x = x+1
return x
Or if even enumerate() is not allowed, simply use range() loop till len(correctanswer) and get elements from each index.
I am writing a program in python that calculates the number equivalent of a string and prints it. (By number equivalent, I mean a=1 b=2 ... so the seventh letter in the alphabet is converted to the number 7.) So if the word was abc then it would turn out to be 123. And if possible, the numbers (in my example 123) are added. (So in my example the result that is printing would be 6.) I tried doing this letter by letter, using the ord() function. But that ended up being where you type each letter and press enter and then add spaces for empty letters. The code was meant to calculate the number value of each letter in the word, add all of the values, and tell True if the number was 100 or false if it was anything else. Here it is... `
#collect info
ar=raw_input('Letter')
br=raw_input('Letter')
cr=raw_input('Letter')
dr=raw_input('Letter')
er=raw_input('Letter')
fr=raw_input('Letter')
gr=raw_input('Letter')
hr=raw_input('Letter')
ir=raw_input('Letter')
jr=raw_input('Letter')
kr=raw_input('Letter')
lr=raw_input('Letter')
mr=raw_input('Letter')
nr=raw_input('Letter')
#ord it
ap=ord(ar)
bp=ord(br)
cp=ord(cr)
dp=ord(dr)
ep=ord(er)
fp=ord(fr)
gp=ord(gr)
hp=ord(hr)
ip=ord(ir)
jp=ord(jr)
kp=ord(kr)
lp=ord(lr)
mp=ord(mr)
np=ord(nr)
#sub 96
a=(ap-96)
b=(bp-96)
c=(cp-96)
d=(dp-96)
e=(ep-96)
f=(fp-96)
g=(gp-96)
h=(hp-96)
i=(ip-96)
j=(jp-96)
k=(kp-96)
l=(lp-96)
m=(mp-96)
n=(np-96)
#chk for 96
if a==-64:
a=0
if b==-64:
b=0
if c==-64:
c=0
if d==-64:
d=0
if e==-64:
e=0
if f==-64:
f=0
if g==-64:
g=0
if h==-64:
h=0
if i==-64:
i=0
if j==-64:
j=0
if k==-64:
k=0
if l==-64:
l=0
if m==-64:
m=0
if n==-64:
n=0
#add
value=a+b+c+d+e+f+g+h+i+j+k+l+m+n
#spit
if value==100:
print 'True (100)'
if value<100 or value>100:
print 'False (', value, ')'`
I can't figure out how to do this. So, an explanation would be nice, a full code re-write would be enjoyed, but not required.
-Adam
P.S. If there is anything I forgot to add to this question, just tell me.
Assuming everything is lowercase and input is only a-z
sum((ord(c) - ord('a') + 1 for c in s))
>>> from string import lowercase,uppercase
>>> alphabet = lowercase+uppercase
>>> mapper = {c:i for i,c in enumerate(alphabet,start=1)}
>>> aword = "Letter"
>>> sum(mapper[l] for l in aword)
106
Create a dictionary which maps a character c to the position it is in the alphabet i. We then pass sum a generator expression which looks up i for each character in aword, resulting in all the character values being summed.
>>> aword="iabcdefghijklm"
>>> value=sum(map(ord,aword),(1-ord("a"))*len(aword))
>>> print value==100, value
True 100
>>>