I have a problem concerning a comparison between a char key in a dict and a char within a list.
The Task is to read a text and count all beginning letters.
I have a list with chars:
bchars = ('i','g','h','n','h')
and a dict with the alphabet and frequency default to zero:
d = dict(dict())
for i in range(97,123):
d[i-97]={chr(i):0}
no i want to check like the following:
for i in range(len(bchars)):
for j in range(len(d)):
if(bchars[i] in d[j]):
d[j][chr(i+97)] +=1
else:
d[j][chr(i+97)] +=0
so if the char in the list is a key at the certain position then += 1 else += zero
I thought by using a if/else statement I can bypass the KeyError.
Is there any more elegant solution for that?
The specific problem is that you check whether bchars[i] is in d[j], but then the key you actually use is chr(i+97).
chr(i+97) is the index of the ith character in bchars, but mapped to ASCII characters starting from 'a'. Why would you want to use this as your key?
I think you really want to do:
for i in range(len(bchars)):
for j in range(len(d)):
if(bchars[i] in d[j]):
d[j][bchars[i]] += 1
else:
d[j][bchars[i]] = 1
Note that you can't use += in the else; remember how you literally just checked whether the key was there and decided it wasn't?
More broadly, though, your code doesn't make sense - it is overcomplicated and does not use the real power of Python's dictionaries. d looks like:
{0: {'a': 0}, 1: {'b': 0}, 2: {'c': 0}, ...}
It would be much more sensible to build a dictionary mapping character directly to count:
{'a': 0, 'b': 0, 'c': 0, ...}
then you can simply do:
for char in bchars:
if char in d:
d[char] += 1
Python even comes with a class just for doing this sort of thing.
The nested dictionary doesn't seem necessary:
d = [0] * 26
for c in bchars:
d[ord(c)-97] += 1
You might also want to look at the Counter class in the collections module.
from collections import Counter
bchars = ('i','g','h','n','h')
counts = Counter(bchars)
print(counts)
print(counts['h'])
prints
Counter({'h': 2, 'i': 1, 'g': 1, 'n': 1})
2
Related
I write a small program using comprehension list python and I need to assign a value to dictionary.
It gives me syntax error.
all_freq = {}
Input = 'google.com'
[all_freq[s] += 1 if s in Input else all_freq[s] = 1 for s in Input]
It says "[" was not closed.
Could you please help me.
Use a normal for loop, not a list comprehension, as you are not trying to create a list of anything.
all_freq = {}
for s in Input:
if s in all_freq:
all_freq[s] += 1
else:
all_freq[s] = 1
which can be simplified slightly to
all_freq = {}
for s in Input:
if s not in all_freq:
all_freq[s] = 0
all_freq[s] += 1
which can be replaced entirely with
from collections import Counter
all_freq = Counter(Input)
Just inspired by earlier post, you can also do this way:
Of course, Counter is the best to do quick tallying.
from collections import defaultdict
all_freq = defaultdict(int) # initialize the dict to take 0, if key is not existing yet
for s in 'google': # each for-loop, just increment the *count* for corresponding letter
all_freq[s] += 1
print(all_freq)
defaultdict(<class 'int'>, {'g': 2, 'o': 2, 'l': 1, 'e': 1})
I am writing a python program to find character sequence in a word. But the program is giving the unexpected result.
I have found a similar type program that works perfectly.
To me I think the two program is quite similar but dont know why one of them does not work
The program that is not working:
# Display the character sequence in a word
dict={}
string=input("Enter the string:").strip().lower()
for letter in string:
if letter !=dict.keys():
dict[letter]=1
else:
dict[letter]=dict[letter]+1
print(dict)
The program that is working:
def char_frequency(str1):
dict = {}
for n in str1:
keys = dict.keys()
if n in keys:
dict[n] += 1
else:
dict[n] = 1
return dict
print(char_frequency('google.com'))
The output for the first program is giving:
Enter the string:google.com
{'g': 1, 'c': 1, 'm': 1, 'o': 1, 'l': 1, '.': 1, 'e': 1}
The output for the second program is:
{'c': 1, 'e': 1, 'o': 3, 'g': 2, '.': 1, 'm': 1, 'l': 1}
The above is the correct output.
Now the questions in my mind.
i. Why the first program is not working correctly?
ii. Is the ideology of these two programs are different?
Actually, there's a little mistake is in the if statement you have used. Just have a look at the below modified program.
Note: Also make sure not to use pre-defined data type names like dict as variable names. I have changed that to d here.
>>> d = {}
>>>
>>> string=input("Enter the string:").strip().lower()
Enter the string:google.com
>>>
>>> for letter in string:
... if letter not in d.keys():
... d[letter] = 1
... else:
... d[letter] = d[letter] + 1
...
>>> print(d)
{'g': 2, 'o': 3, 'l': 1, 'e': 1, '.': 1, 'c': 1, 'm': 1}
>>>
You can have also have a look at the below statements executed on the terminal.
Comparing a key with d.keys() will always return False as key is a string here and d.keys() will always be an object of type dict_keys (Python3) and a list (Python2).
>>> d = {"k1": "v1", "k3": "v2", "k4": "Rishi"}
>>>
>>> d.keys()
dict_keys(['k1', 'k3', 'k4'])
>>>
>>> "k1" in d
True
>>>
>>> not "k1" in d
False
>>>
>>> "k1" == d.keys()
False
>>>
>>> "k1" not in d
False
>>>
Answers of your 2 questions:
Because the statement letter != dict.keys() is always True so no increment in key counts. Just change it to letter not in dict.keys(). And it is better to use d in place of dict so that the statement will look like letter not in d.keys().
Logic of both the programs are same i.e. iterating over the dictionary, checking for an existence of key in dictionary. If it does not exist, create a new key with count 1 else increment the related count by 1.
Thank you v. much.
This line is nonsensical:
if letter !=dict.keys():
letter is a length one str, while dict.keys() returns a key view object, which is guaranteed to never be equal to a str of any kind. Your if check is always false. The correct logic would be:
if letter not in dict:
(you could add .keys() if you really want to, but it's wasteful and pointless; membership testing on a dict is checking its keys implicitly).
Side-note: You're going to confuse the crap out of yourself by naming a variable dict, because you're name-shadowing the dict constructor; if you ever need to use it, it won't be available in that scope. Don't shadow built-in names if at all possible.
This question already has answers here:
Why does range(start, end) not include end? [duplicate]
(11 answers)
Closed 4 years ago.
I'm currently trying to solve a problem of counting repeating characters in a row in Python.
This code works until it comes to the last different character in a string, and I have no idea how to solve this problem
def repeating(word):
count=1
tmp = ""
res = {}
for i in range(1, len(word)):
tmp += word[i - 1]
if word[i - 1] == word[i]:
count += 1
else :
res[tmp] = count
count = 1
tmp = ""
return res
word="aabc"
print (repeating(word))
The given output should be {'aa': 2, 'b': 1, 'c' : 1},
but I am getting {'aa': 2, 'b': 1}
How do I solve this?
In this case, you can use the collections.Counter which does all the work for you.
>>> from collections import Counter
>>> Counter('aabc')
Counter({'a': 2, 'c': 1, 'b': 1})
You can also iterator over the letters in string, since this is iterable. But then I would use the defaultdict from collections to save on the 'counting' part.
>>> from collections import defaultdict
>>>
>>> def repeating(word):
... res = defaultdict(int)
... for letter in word:
... res[letter] +=1
... return res
...
>>> word="aabc"
>>> print (repeating(word))
defaultdict(<type 'int'>, {'a': 2, 'c': 1, 'b': 1})
I would recommend using Counter from the collections module. It does exactly what you are trying to achieve
from collections import Counter
wourd = "aabc"
print(Counter(word))
# Counter({'a': 2, 'b': 1, 'c': 1})
But if you want to implement it yourself, I should know that str is an Iterable. Hence you are able to iterate over every letter with a simple loop.
Additionally, there is something called defaultdict, which comes quite handy in this scenario. Normally you have to check whether a key (in this case a letter) is already defined. If not you have to create that key. If you are using a defaultdict, you can define that every new key has a default value of something.
from collections import defaultdict
def repeating(word):
counter = defaultdict(int)
for letter in word:
counter[letter] += 1
return counter
The result would be similar:
In [6]: repeating('aabc')
Out[6]: defaultdict(int, {'a': 2, 'b': 1, 'c': 1})
I'm so stuck on this task. I have a task where I need to write a program in python 2.7 which prompts a user to input a string and then the program needs to return the number of times the letters in that string occur. for example the word "google.com" must return 'o': 3, 'g': 2, '.': 1, 'e': 1, 'l': 1, 'm': 1, 'c': 1
I know i need to use the list() function but all i have so far is:
string = raw_input("Enter a string: ")
newString = list(string)
and then i get stuck from there because I don't know how to make the program count the number of times the letters occur. I know there must be a for loop in the syntax but I'm not sure how I'm going to use it in this case.
NB: We haven't been introduced to dictionaries or imports yet so please keep it as simple as possible. Basically the most round about method will work best.
You can handle this problem directly with the help of count function.
You can start with an empty dictonary and add each character of the entered string and its count to the dictionary.
This can be done like this..!
string = raw_input("Enter a string: ")
count_dict = {}
for x in string:
count_dict[x] = string.count(x)
print count_dict
#input : google.com
# output : {'c': 1, 'e': 1, 'g': 2, 'm': 1, 'l': 1, 'o': 3, '.': 1}
Update:
Since you haven't been introduced to dictionary and imports, you can use the below solution.
for i in set(string):
print("'{}'".format(i), string.count(i), end=",")
Use Counter:
from collections import Counter
string = "google.com"
print(Counter(string))
Other way, create a dictionary and add chars looping through your string.
dicta = {}
for i in string:
if i not in dicta:
dicta[i] = 1
else:
dicta[i] += 1
print(dicta)
This question already has answers here:
Why dict.get(key) instead of dict[key]?
(14 answers)
Closed 4 years ago.
sentence = "The quick brown fox jumped over the lazy dog."
characters = {}
for character in sentence:
characters[character] = characters.get(character, 0) + 1
print(characters)
I don't understand what characters.get(character, 0) + 1 is doing, rest all seems pretty straightforward.
The get method of a dict (like for example characters) works just like indexing the dict, except that, if the key is missing, instead of raising a KeyError it returns the default value (if you call .get with just one argument, the key, the default value is None).
So an equivalent Python function (where calling myget(d, k, v) is just like d.get(k, v) might be:
def myget(d, k, v=None):
try: return d[k]
except KeyError: return v
The sample code in your question is clearly trying to count the number of occurrences of each character: if it already has a count for a given character, get returns it (so it's just incremented by one), else get returns 0 (so the incrementing correctly gives 1 at a character's first occurrence in the string).
To understand what is going on, let's take one letter(repeated more than once) in the sentence string and follow what happens when it goes through the loop.
Remember that we start off with an empty characters dictionary
characters = {}
I will pick the letter 'e'. Let's pass the character 'e' (found in the word The) for the first time through the loop. I will assume it's the first character to go through the loop and I'll substitute the variables with their values:
for 'e' in "The quick brown fox jumped over the lazy dog.":
{}['e'] = {}.get('e', 0) + 1
characters.get('e', 0) tells python to look for the key 'e' in the dictionary. If it's not found it returns 0. Since this is the first time 'e' is passed through the loop, the character 'e' is not found in the dictionary yet, so the get method returns 0. This 0 value is then added to the 1 (present in the characters[character] = characters.get(character,0) + 1 equation).
After completion of the first loop using the 'e' character, we now have an entry in the dictionary like this: {'e': 1}
The dictionary is now:
characters = {'e': 1}
Now, let's pass the second 'e' (found in the word jumped) through the same loop. I'll assume it's the second character to go through the loop and I'll update the variables with their new values:
for 'e' in "The quick brown fox jumped over the lazy dog.":
{'e': 1}['e'] = {'e': 1}.get('e', 0) + 1
Here the get method finds a key entry for 'e' and finds its value which is 1.
We add this to the other 1 in characters.get(character, 0) + 1 and get 2 as result.
When we apply this in the characters[character] = characters.get(character, 0) + 1 equation:
characters['e'] = 2
It should be clear that the last equation assigns a new value 2 to the already present 'e' key.
Therefore the dictionary is now:
characters = {'e': 2}
Start here http://docs.python.org/tutorial/datastructures.html#dictionaries
Then here http://docs.python.org/library/stdtypes.html#mapping-types-dict
Then here http://docs.python.org/library/stdtypes.html#dict.get
characters.get( key, default )
key is a character
default is 0
If the character is in the dictionary, characters, you get the dictionary object.
If not, you get 0.
Syntax:
get(key[, default])
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.
If d is a dictionary, then d.get(k, v) means, give me the value of k in d, unless k isn't there, in which case give me v. It's being used here to get the current count of the character, which should start at 0 if the character hasn't been encountered before.
I see this is a fairly old question, but this looks like one of those times when something's been written without knowledge of a language feature. The collections library exists to fulfill these purposes.
from collections import Counter
letter_counter = Counter()
for letter in 'The quick brown fox jumps over the lazy dog':
letter_counter[letter] += 1
>>> letter_counter
Counter({' ': 8, 'o': 4, 'e': 3, 'h': 2, 'r': 2, 'u': 2, 'T': 1, 'a': 1, 'c': 1, 'b': 1, 'd': 1, 'g': 1, 'f': 1, 'i': 1, 'k': 1, 'j': 1, 'm': 1, 'l': 1, 'n': 1, 'q': 1, 'p': 1, 's': 1, 't': 1, 'w': 1, 'v': 1, 'y': 1, 'x': 1, 'z': 1})
In this example the spaces are being counted, obviously, but whether or not you want those filtered is up to you.
As for the dict.get(a_key, default_value), there have been several answers to this particular question -- this method returns the value of the key, or the default_value you supply. The first argument is the key you're looking for, the second argument is the default for when that key is not present.