Select dictionary keys and put them into a list - python

I would be very happy if somebody could help me solve the following exercise about dictionaries.
Write a function that takes a dictionary where every key is a string and the value is a whole number (integer) and returns a sorted list of the keys corresponding to their even numbers.
Example
dictionary = {'Kurt':35, 'Alex':26, 'Laura':31}
Should return
mylist= ['Alex'] # because it's the only key that has a matching even number
This is my code
def even_numbers (mydict):
mylist = []
for num in mydict.values():
if num % 2 == 0:
mylist.append(mydict.keys())
return mylist
Please help me

use dict.items instead of dict.values:
def even_numbers (mydict):
mylist = []
for key, num in mydict.items():
if num % 2 == 0:
mylist.append(key)
return mylist
when you do mylist.append(mydict.keys()) you'll have a list of keys for every pair value, so the need of using dict.items which return an iterable of key, value pair

Related

The count() method counts wrong

Here is my task to solve.
For a list of integers, find and print the items that appear in the list
only once. Items must be printed in the order in which they are
are in the incoming list.
I wrote the code but it also counts two and three digit numbers as a single digits. What's the problem?
x = []
a = input()
a.split(" ")
for i in a:
if a.count(i) == 1:
x.append(i)
print(x)
User Mechanical Pig provides the answer, split does not work in-place, since you're discarding its result what you're looking at is the count of each character in the string, not each space-separated sub-string.
The standard library also contains a collection which is ready-made for this use-case: collections.Counter. You can just give it a sequence of items and it'll collate the counts, which you can then filter:
print([k for k, v in collections.Counter(a.split()).items() if v == 1])
a.split(" ") does not change the value of a, so it is still a string and not a list. Hence when you iterate over a, you only get single characters.
str.split is a method that returns a list, but does not magically turn the string into a list. So you need to assign the value it returns to a variable (for example, to a, if you don't want to hold on to the input string).
You can assign the variable as mentioned above or you can directly use the split function in the loop.
x = []
a = input()
for i in a.split(" "):
if a.count(i) == 1:
x.append(i)
print(x)
or split when you are reading the input.
x = []
a = input().split(" ")
for i in a:
if a.count(i) == 1:
x.append(i)
print(x)
Using the Counter class from the collections module is the right way to do this but here's another way without any imports where you effectively have your own limited implementation of a Counter:
a = '1 2 3 4 4 5 6 7 7 7'
d = {}
for n in a.split():
d[n] = d.get(n, 0) + 1
for k, v in d.items():
if v == 1:
print(k)
Output:
1
2
3
5
6

compare key and values at corresponding index in python

There is dictionary in python.key and value spelling is compared.if the mistake is greater than or equal to 2 than print incorrect
input={"their":"thuyr"}
output=incorrect(because t=t,h=h but e!=u,i!=y).
My problem is that i was unable to compare t==t,h==h,e==u,i==y.
The below code shows count value 22 but count value must be 2 because only two words mismatches with their
def find_correct(words_dict):
count=0
for key,value in words_dict.items():
for val in value:
for ky in key:
if(val!=ky):
count+=1
return count
print(find_correct({"their":"thuor"}))
It's because you're using nested loops. It's comparing each letter of "t" in "their" with each 5 letters in "thuor". Instead, just use a single loop like this:
def find_correct(words_dict):
count=0
for key,value in words_dict.items():
for val, ky in zip(value, key):
if(val!=ky):
count+=1
return count

counting the number of terms that are not repeated in the python list

the question was actually like
Write a program that says the number of terms to be replaced to get all the numbers same in the list
ex
a=[1,1,2,1,1,4,1,1]
then the expected output is 2
I guess you are looking for the minimum number of numbers to be replaced so that all numbers are the same.
# store occurrences of each number in a dictionary
d = {}
for i in a:
if i not in d:
d[i] = 1
else:
d[i] += 1
# get key with max value: i.e. most frequent number in initial list
max_k = max(d, key=d.get)
# delete element that appears most often in the initial list
del d[max_k]
# count rest of the numbers => numbers to be replaced
nums_to_replaces = sum([d[k] for k in d])
Your wording is a bit strange.
If you want the number of items that are not one:
len([i for i in a if i!=1])
or
len(a)-a.count(1)
if you want the unique set of numbers that are not repeated as the question says:
len([i for i in set(a) if a.count(i)==1])
You could iterate over the list and make a dictionary of the occurrence:
occurrences = {}
for x in range(len(a)):
if a[x] not in occurences:
occurrences[x] = 1
else:
occurrences[x] += 1
Now you could have a dict of the occurrences and you could do this to get the number of terms to be replaced:
nums = list(occurrences.values()).sort(reverse=True) # Sort I descending order with num of repetitions
print(sum(nums[1:])) # Add occurrences of all but the element with max occurrences
#Or just subtract the max occurrence from the length of list
print(len(a) - max(list(occurrences.values())))
This will give you the least number of changes need to be made. In this way you cannot specify which element you want the whole list to contain

Manipulation Searching Dictionary with list as value in Python

I have a dictionary like this:
d={1:[2,3,4],2:[1,3,4],3:[1,2],4:[1,2,3]}.
I need to do for example: In the key 1 I have the list [2,3,4]. I have to count the number of connections between the element of the list as value in all the keys.
So I have to verify if in key 2 there are as elements 3or 4 and also the key 3with the element 4.
This research has to continue for all the key of the dictionary d.
At the end of searching in all the keys, I had to count the number of the couples found. In the example I have only count=2 because key 2 is connected with 3 and 4, but 3 isn't connected to 4. Repetitions aren't required. So I'm not interested in the couple 4-2 if I had already found (and counted) the couple 2-4.
I tried to implement for the first key:
`
d={}
d={1:[2,3,4],2:[1,3,4],3:[1,2],4:[1,2,3]}
values=[]
count = 0
#for key in d:
values = d[1]
for value in values:
for i in (d[value]):
print "i: ",i
if i in values:
count += 1
print " count: ", count
print ".........."
print(count)
`
But, in this way count=5 because it count also the reversed couples. I have to specify something so count will be count=3. How can do that?
d={}
d={1:[2,3,4],2:[1,3,4],3:[1,2],4:[1,2]}
print d
values=[]
for key in d:
count = 0
values = d[key]
for value in values:
for i in (d[value]):
if i in values:
count += 1
print "count: ",count/2, " key: ", key

Python code not appending 'Free Period' when I want it to

list1 = []
elective = []
prereq = []
someNumber = 1
dict2 = {
1: SEM2period1, 2: SEM2period2,
2: SEM2period3, 4: SEM2period4,
5: SEM2period5, 6: SEM2period6,
7: SEM2period7, 8: SEM2period8
}
for key, dlist in dict2.items():
if not dlist:
list1.append("Free Period")
someNumber += 1
continue
for item in dlist:
if item in list1:
continue
elif item in elective:
elecStorage.append(item)
elif item in prereq:
list1.append(item)
someNumber += 1
break
if someNumber > len(list1):
for index in elecStorage:
if index in list1:
break
else:
list1.append(index)
someNumber += 1
elecStorage[:] = []
break
Notes: Electives and Prereq both contain strings like "Calculus 1" (for prereq), or "Astronomy" (for elective.) The variables in dict2 are lists that contain class (as in classroom) names that were called earlier by the function.
What the snippet that starts out with "for key, dlist in dict2.items()" should do is search through the the elements of the first list, checking first if there is a list, if there isn't then append "Free Period" into the list. Then it should check if any of the elements of the list exist in prereq, and finally if there isn't, append something from electives into it. (Because if it gets past the first condition, it's safe to assume there is at least an elective.) and then loop back around and perform the same operation to the next list of elements.
Issue is, unless all of the lists contain nothing, it won't append 'Free Period' and I can't figure out why.
Ideas?
Something in your SEM*period* is likely returning an empty list, and not None. The correct checks for empty list '[]', is 'if list1 == []' or 'if len(list1) == 0'.
None is placeholder meaning a non-existing object. [] is a valid list object, it just has no entries in the list. 'if not foo' is simply checking for None, not an empty list.
You should verify the contents of your SEM2period variables, this is hard to diagnose without them. I didn't follow the rest of your logic, but it's really just the first block in the loop that you are interested in, yes? You may have a list containing an empty list, perhaps? That would mess up your logic:
d2 = {1:['elec'], 2:[]}
for key, dlist in d2.items():
if not dlist:
print 'empty!'
else:
print dlist
gives you
['elec']
empty!
but
d2 = {1:['elec'], 2:[[]]}
for key, dlist in d2.items():
if not dlist:
print 'empty!'
else:
print dlist
gives you
['elec']
[[]]

Categories

Resources