Unexpected Behaviour of if statement inside loop over d.items() - if-statement

Using Python 3.3 I want to loop over d.items() and return matches based on if condition. Here is the code:
d = {'mohammed': '123456789', 'john': '1230012'}
for k, v in d.items():
if k == 'mohammed' and v == '123456789':
print("Match")
else:
print("No Match")
I expect to print "Match", however what I get is that both the statements print in reverse, i.e.,
No Match
Match
How to get the code print only the right statement? Any help is appreciated.

Dictionaries are not ordered, so the entries in d may not be stored in the same order you typed them. Therefore, the order in which d.items() iterates over the entries in d cannot be predicted exactly.
When you iterate over d.items(), you are iterating over all key,value pairs. Therefore, if a pair matches your if-condition, Match will be printed. By the same reasoning, if a pair does not match your if-condition, No Match will be printed.
In your case, the order of key,value pairs during the iteration over d.items() is exactly the opposite of the order in which you've entered them. Let's take a look at this:
The first key,value pair to be considered is 'john': '1230012'. This does not match your if-condition. Therefore No Match is printed.
The next pair is 'mohammed': '123456789', which does match your if-condition. Therefore Match is printed.
You can confirm this by adding a print(k,v) before your if-statement
Now, if for some reason, you want features of dictionary, and you want to maintain the order in which you've entered your data, then I'd recommend using collections.OrderedDict
In your post, you say "I expect to print Match". I think therefore, what you're looking for, is a way to check if there are any key,value pairs in the dictionary that satisfy your if-condition. Here are two ways in which you can accomplish this:
d = {'mohammed': '123456789', 'john': '1230012'}
found = False
for k,v in d.items():
if k == 'mohammed' and v == '123456789':
print("Match")
found = True
if not found: # equivalently, if found == False:
print("No Match")
This will print Match as many times as there are key,value pairs that do match your if-condition. If however, you want to print Match only once even if multiple pairs match your if-condition, then you make a small modification to the above code:
d = {'mohammed': '123456789', 'john': '1230012'}
found = False
for k,v in d.items():
if k == 'mohammed' and v == '123456789':
found = True
if found:
print("Match")
else:
print("No Match")
Of course, there's a handy one-liner for all of this:
if any(k == 'mohammed' and v == '123456789' for k,v in d.items()):
print("Match")
else:
print("No Match")

Firstly, dictionaries(Dict objects) are un ordered so you can't be sure which item is accessed/iterated first.
Secondly, by the looks of it(assuming) that you want just a Match or No Match for an output.
You can do this by simple having a boolean;
matched = False
for k, v in d.items():
if k == 'mohammed' and v == '123456789':
print("Match")
matched = True
break
if not matched:
print("No Match")
OR
If you want to access these in order, you can change your data structure to something like
[('muhammad','somevalue'),(),...]
Then you may iterate on this list and have something like
for obj in d:
t_val_1, t_val_2 = obj
if t_val_1 == 'mohammed' and t_val_2 == '123456789':
print("Match")
else:
print("No Match")

Related

how to extract elements from a string with a trasversal loop

I have this little code:
> def names():
prefixes='JKLMNOPQ'
suffix='ack'
for letter in prefixes:
if letter == 'O'or 'Q' in prefixes:
print letter +'u' +suffix
else:
print letter+suffix
And I would like to achieve the following format after printing it:
Jack
Kack
Lack
Mack
Nack
Ouack
Pack
Quack
However I get this one:
Juack
Kuack
Luack
Muack
Nuack
Ouack
Puack
Quack
For any reason I cannot see the if statement is not work. How can I manage to make it work?
You probably might want to change your code to:
def names():
prefixes='JKLMNOPQ'
suffix='ack'
for letter in prefixes:
if letter == 'O' or letter == 'Q':
print letter +'u' +suffix
else:
print letter+suffix
Your problem is you have a "always" True condition:
def names():
prefixes='JKLMNOPQ'
suffix='ack'
for letter in prefixes:
if letter == 'O'or 'Q' in prefixes: # here
print letter +'u' +suffix
else:
print letter+suffix
'Q' is always in prefixes - the condition is alwas True.
Use if letter in 'O Q': instead.

Terminating raw_input based on the ascii value of the string

I am new to python.
My Issue- need to terminate the raw_input if no input is passed
I am basically asking user for number of key-value pairs to be added to dictionary. Then adding the key-value pairs in dictionary. Later querying the dictionary which should result value if key exist, else print Not found.
I searched the Stack Overflow and found solution in terms of timer but I am trying to use ord function to get ascii value of string and check it against null that is ascii value of 0. My code does not seem to terminate, please advice on necessary changes in code.
Please find the code that I am using in the program:
def convert_to_ascii(text):
return "".join(str(ord(char)) for char in text)
n=int(raw_input().rstrip())
phonebook = dict(raw_input().split() for i in range(n))
print phonebook
list1=[]
while True:
choice = raw_input()
temp=convert_to_ascii(choice)
print temp
if temp != '0':
list1.append(choice)
else:
break
for word in list1:
if word in phonebook :
print '{0}={1}'.format(word,phonebook[word])
else:
print 'Not found'
You should have the empty string '' instead of '0' as your check. This code worked for me. I also added some prints in the raw_inputs to help me look through your code, but the only change that matters is the '0' to '':
def convert_to_ascii(text):
return "".join(str(ord(char)) for char in text)
n=int(raw_input('How many entries in your phonebook?\n').rstrip())
phonebook = dict(raw_input('Please enter "[name] [number]" for entry '+str(i+1)+':\n').split() for i in range(n))
print phonebook
list1=[]
while True:
choice = raw_input('Who do you want to choose?\n')
temp=convert_to_ascii(choice)
if temp != '': #<-- changed to empty string from '0'
list1.append(choice)
else:
break
for word in list1:
if word in phonebook :
print '{0}={1}'.format(word,phonebook[word])
else:
print word,'was not found'

Counting two words in a string

I have to count two words 'cat' and 'dog' from a string.
If the counts are equal, I would like to return True else false.
For example, for input "dogdoginincatcat" my method should return True.
Here is my code,
def cat_dog(str):
count=0
count1=0
for i in range(len(str)):
if str[i:i+3] == 'cat':
count=count+1
if str[i:i+3] == 'dog':
count1=count+1
if count == count1:
return True
else:
return False
cat_dog('catdog')
just one line to do this using count on a string:
z= "dogdoginincatcat"
print(z.count("cat")==z.count("dog"))
First, DON'T use str (the string class) as a variable name. While Python won't cry at that very moment, you'll regret it later.
Second, it doesn't look like the count and count1 are indented as inside blocks of the 'if' statements, so your code is seen as:
for i in range(len(str))
if something:
pass
count = count + 1
if something_else:
pass
count1 = count1 + 1
Other than that, your code seems to work

Checking charcters in a string and outputing a Single message

a_lst = ['chair','gum','food','pizza']
letter = 'x'
for word in a_lst:
if letter not in word:
print ('no',letter)
elif letter in word:
print ('yes',letter)
Output:
no x
no x
no x
no x
Is there a way i can iterate though each item in "a_lst", check if each item has letter 'x'. if no item has letter 'x' print 'no x' just Once. If a word contains letter 'x', print 'yes x' just Once.
I think my logic is flawed somewhere.
Any suggestions?
Thanks
You could do this:
letter = 'x'
result = [a for a in a_lst if letter in a]
if result:
print('yes', letter)
else:
print('no', letter)
Explanation:
result will be [] if none of the words in a_lst has the letter. When you do a if result on an empty list, it returns False, otherwise it returns True. The conditional statements check and print the output statement accordingly.
Another way to do it in python is to use the filter function:
if filter(lambda x: letter in x, a_lst):
print('yes', letter)
else:
print('no', letter)
Yet another way to do it is to use any:
if any(letter in word for word in a_list):
print('yes', letter)
else:
print('no', letter)
any(letter in word for word in a_list) returns True if any of the words have the letter.
You can use the any function!
if any(letter in word for word in a_lst):
print('yes', letter)
else:
print('no', letter)
Have you tried something like this:
a = ['chair', 'gum', 'food', 'pizza']
letter = 'a'
result = 'no ' + letter
k = 0
for i in a:
if letter in a[k]:
print(a[k])
result = 'yes ' + letter
k += 1
print(result)

return result of palindrome check with for-loop in python

I am doing a palindrome-check assignment in Python. I have to use a for-loop to check if it is a palindrome or not.
I think that I am on to the right track, but I am having trouble returning the result of the loop. When running the program it always returns True, even when it is not a palindrome. I would really need help to see if I have done the for-loop correctly and how to return the correct result.
My program as it is now looks like this:
def main ():
showResult(testPalindrome(newText()))
def newText():
word = raw_input ('Hi, insert a word:')
clean = (',','!','.')
for i in clean:
cleanedText = word.replace(i, "").lower()
return cleanedText
def testPalindrome(cleanedText):
testword = cleanedText
list = [testword]
for i in range(len(list)/2):
if list[i] != list [-i-1]:
continue
else:
break
def showResult(palindrome):
if True:
print 'Yes, it is a palindrome '
else:
print 'No, it is not palindrome'
main ()
You never return anything from test_palindrome. Remember that it is not a palindrome if any letters fail to match, but all must match to pass, so:
for i in range(len(list)/2):
if list[i] != list [-i-1]:
continue
else:
break
Should become
for i in range(len(list)/2):
if list[i] != list [-i-1]:
return False
return True
Also, to make your code more robust, you could replace clean with string.punctuation (remembering to import string).
For testing is a string is a palindrome, compare it with its reverse.
In [1]: p = 'this is a test'
In [2]: p[::-1]
Out[2]: 'tset a si siht'
In [3]: p == p[::-1]
Out[3]: False
In [4]: q = 'racecar'
In [5]: q == q[::-1]
Out[5]: True