Firstly, I have to say that i'm a beginner in python.
Then, here is my problem :
I have a dictionary like this one :
dic = {}
dic["a", 1] = 0
dic["a", 2] = 2
dic["b", 1] = 5
dic["b", 2] = 0
...
And I want to do a for-loop with this dictionary to test all the keys' pair and find which ones are equivalent to 0 in a if statement.
I thought of that :
for [co, l], ch in dic.items():
if [co, l] == 0:
But the if statement is never true, so I can't do anything.
Does anyone could provide me some help, please ?
Thanks
[co, l] is the key (or copy of it); it is a list with 2 items, and cannot be equal to 0. Instead you want to test the ch value and then perhaps do something with the key.
dic = {}
dic["a", 1] = 0
dic["a", 2] = 2
dic["b", 1] = 5
dic["b", 2] = 0
...
for [co, l], ch in dic.items():
if ch == 0:
print("The value for key {}, {} was 0".format(co, l))
Or if you want to iterate by the key:
for key in dic:
if dic[key] == 0:
print("The value for key {} was 0".format(key))
As per the comments:
for ch in dic.items():
if ch == 0:
[co, l] is never 0. I think you mean to test ch.
for [co, l], ch in dic.items():
... print [co, l], ch
...
['a', 1] 0
['b', 2] 0
['b', 1] 5
['a', 2] 2
Related
I've got two problems with the following code
S = "acbcbba"
def count_letters(text):
result = {}
for letter in text:
if letter.isalpha():
if letter.lower() in result.keys():
result[letter.lower()] += 1
else:
result[letter.lower()] = 1
print(result)
return(result)
count_letters(S)
Firstly, I can't figure out how to modify it so it only returns 1 dictionary instead of as many dictionaries as there letters in the string.
Secondly, I then need to be able to access each key to figure out if the value associated with it is odd and return the keys that have odd values associated with them?
Does anyone have any ideas of how to do this?
It isn't returning multiple dictionaries, it is returning 1 dictionary, and printing the others. Just remove your print statement.
Regarding querying for items which have an odd number of counts you can use a list comprehension of the dictionary's items() and filter out by their value (i.e. count) being odd.
>>> d = count_letters(S)
>>> d
{'a': 2, 'c': 2, 'b': 3}
>>> [key for key, value in d.items() if value % 2 == 1]
['b']
If you want a list of the key value pairs then you can do something similar
>>> [(key, value) for key, value in d.items() if value % 2 ==1 ]
[('b', 3)]
All was about an indentation but here is a solution
S = "acbcbba"
def count_letters(text):
result = {}
for letter in text:
if letter.isalpha():
if letter.lower() in result.keys():
result[letter.lower()] += 1
else:
result[letter.lower()] = 1
print(result)
return(result)
count_letters(S)
output
{'a': 2, 'c': 2, 'b': 3}
anyway there was no reason to return if there is print in the function or you could return result only and thereafter print it like the following
S = "acbcbba"
def count_letters(text):
result = {}
for letter in text:
if letter.isalpha():
if letter.lower() in result.keys():
result[letter.lower()] += 1
else:
result[letter.lower()] = 1
return(result)
print(count_letters(S))
You can use built-in functions for that. For counting a specific character, just do S.count('a'). For getting a dictionary with all characters you could do something like that
S = "acbcbba"
my_dict = {k:S.count(k) for k in set(S)}
I have two lists, one is of form:
A = ["qww","ewq","ert","ask"]
B = [("qww",2) ,("ert",4) , ("qww",6), ("ewq" , 5),("ewq" , 10),("ewq" , 15),("ask",11)]
I have to process such that final output is
C = A = [("qww",8),("ewq",20),("ert",4),("ask",11)]
for that I written code:
# in code temp_list is of form A
# in code total_list is of form B
# in code final is of form C
def ispresent(key,list):
for qwerty in list:
if qwerty == key:
return 1
else:
return 0
def indexreturn(key,list):
counter = 0
for qwerty in list:
if qwerty != key:
counter = counter + 1
else:
return counter
def mult_indexreturn(key,list):
for i in range(len(list)):
if key == list[i][0]:
return i
final = map(lambda n1, n2: (n1,n2 ), temp_list,[ 0 for _ in range(len(temp_list))])
for object2 in total_list:#****
for object1 in temp_list:
if object2 == object1:
final[ indexreturn(object2,final) ][1] = final[ indexreturn(object2, final) ][1] + object2[mult_indexreturn(object2,total_list)][1]#total_list[ mult_indexreturn(object2,total_list) ][1]
print(final)
it should give output as C type list, but giving nothing
but C = [("qww",0),("ewq",0),("ert",0),("ask",0)]
according to me the main problem is in my looping part ( with **** comment), is there problem with logic or something else.
I gave in lot of codes, so that you can understand how my code working
You can build a dictionary using the method fromkeys() and subsequently you can use the for loop to accumulate integers:
A = ["qww","ewq","ert","ask"]
B = [("qww",2) ,("ert",4) , ("qww",6), ("ewq" , 5),("ewq" , 10),("ewq" , 15),("ask",11)]
C = dict.fromkeys(A, 0)
# {'qww': 0, 'ewq': 0, 'ert': 0, 'ask': 0}
for k, v in B:
C[k] += v
C = list(C.items())
# [('qww', 8), ('ewq', 30), ('ert', 4), ('ask', 11)]
Try this:
from collections import defaultdict
result = defaultdict(int)
for i in A:
result[i] = sum([j[1] for j in B if j[0] == i])
then tuple(result.items()) will be your out put.
Or you can do it in just one line:
result = tuple({i:sum([j[1] for j in B if j[0] == i]) for i in A}.items())
Using collection.defaultdict
Ex:
from collections import defaultdict
A = ["qww","ewq","ert","ask"]
B = [("qww",2) ,("ert",4) , ("qww",6), ("ewq" , 5),("ewq" , 10),("ewq" , 15),("ask",11)]
result = defaultdict(int)
for key, value in B:
if key in A: #Check if Key in A.
result[key] += value #Add Value.
print(result)
Output:
defaultdict(<type 'int'>, {'qww': 8, 'ert': 4, 'ewq': 30, 'ask': 11})
I am new to Python and working on a problem where I have to match a list of indices to a list of value with 2 conditions:
If there is a repeated index, then the values should be summed
If there is no index in the list, then value should be 0
For example, below are my 2 lists: 'List of Inds' and 'List of Vals'. So at index 0, my value is 5; at index 1, my value is 4; at index 2, my value is 3 (2+1), at index 3, may value 0 (since no value associated with the index) and so on.
Input:
'List of Inds' = [0,1,4,2,2]
'List Vals' = [5,4,3,2,1]
Output = [5,4,3,0,3]
I have been struggling with it for few days and can't find anything online that can point me in the right direction. Thank you.
List_of_Inds = [0,1,4,2,2]
List_Vals = [5,4,3,2,1]
dic ={}
i = 0
for key in List_of_Inds:
if key not in dic:
dic[key] = 0
dic[key] = List_Vals[i]+dic[key]
i = i+1
output = []
for key in range(0, len(dic)+1):
if key in dic:
output.append(dic[key])
else:
output.append(0)
print(dic)
print(output)
output:
{0: 5, 1: 4, 4: 3, 2: 3}
[5, 4, 3, 0, 3]
The following code works as desired. In computer science it is called "Sparse Matrix" where the data is kept only for said indices, but the "virtual size" of the data structure seems large from the outside.
import logging
class SparseVector:
def __init__(self, indices, values):
self.d = {}
for c, indx in enumerate(indices):
logging.info(c)
logging.info(indx)
if indx not in self.d:
self.d[indx] = 0
self.d[indx] += values[c]
def getItem(self, key):
if key in self.d:
return self.d[key]
else:
return 0
p1 = SparseVector([0,1,4,2,2], [5,4,3,2,1])
print p1.getItem(0);
print p1.getItem(1);
print p1.getItem(2);
print p1.getItem(3);
print p1.getItem(4);
print p1.getItem(5);
print p1.getItem(6);
Answer code is
def ans(list1,list2):
dic={}
ans=[]
if not(len(list1)==len(list2)):
return "Not Possible"
for i in range(0,len(list1)):
ind=list1[i]
val=list2[i]
if not(ind in dic.keys()):
dic[ind]=val
else:
dic[ind]+=val
val=len(list1)
for i in range(0,val):
if not(i in dic.keys()):
ans.append(0)
else:
ans.append(dic[i])
return ans
To test:
print(ans([0,1,4,2,2], [5,4,3,2,1]))
output:
[5, 4, 3, 0, 3]
Hope it helps
Comment if you dont understand any step
what you can do is sort the indexes and values in an ascending order, and then sum it up. Here is an example code:
import numpy as np
ind = [0,1,4,2,2]
vals = [5,4,3,2,1]
points = zip(ind,vals)
sorted_points = sorted(points)
new_ind = [point[0] for point in sorted_points]
new_val = [point[1] for point in sorted_points]
output = np.zeros((len(new_ind)))
for i in range(len(new_ind)):
output[new_ind[i]] += new_val[i]
In this code, the index values are sorted to be in ascending order and then the value array is rearranged according to the sorted index array. Then, using a simple for loop, you can sum the values of each existing index and calculate the output.
This is a grouping problem. You can use collections.defaultdict to build a dictionary mapping, incrementing values in each iteration. Then use a list comprehension:
indices = [0,1,4,2,2]
values = [5,4,3,2,1]
from collections import defaultdict
dd = defaultdict(int)
for idx, val in zip(indices, values):
dd[idx] += val
res = [dd[idx] for idx in range(max(dd) + 1)]
## functional alternative:
# res = list(map(dd.get, range(max(dd) + 1)))
print(res)
# [5, 4, 3, 0, 3]
Ive got two sets of key value pairs that look like this:
tom = {'coffee': 2, 'hotdog': 1}
and another like this:
namcat = {'hotdog stand':[hotdog, foodstand], 'cafe':[breakfast, coffee]}
Id like to compare whenever a key associated with 'tom' is the same as a value in 'namcat', and if so add 1 to a running total. I think its iterating over key-value pairs with lists that is causing me issues.
for k, v in namcat.items():
for item in v:
for key, value in tom.items():
if value == item:
running_total += 1
Demo:
>>> hotdog = 1
>>> coffee = 2
>>> foodstand = 6
>>> breakfast = 10
>>> tom = {'coffee': 2, 'hotdog': 1}
>>> namcat = {'hotdog stand':[hotdog, foodstand], 'cafe':[breakfast, coffee]}
>>> running_total = 0
>>> for k, v in namcat.items():
for item in v:
for key, value in tom.items():
if value == item:
running_total += 1
>>> running_total
2
This should do it. Hope it helps!
I receive a dictionary as input, and want to return a list of keys for which the dictionary values are unique in the scope of that dictionary.
I will clarify with an example. Say my input is dictionary a, constructed as follows:
a = dict()
a['cat'] = 1
a['fish'] = 1
a['dog'] = 2 # <-- unique
a['bat'] = 3
a['aardvark'] = 3
a['snake'] = 4 # <-- unique
a['wallaby'] = 5
a['badger'] = 5
The result I expect is ['dog', 'snake'].
There are obvious brute force ways to achieve this, however I wondered if there's a neat Pythonian way to get the job done.
I think efficient way if dict is too large would be
countMap = {}
for v in a.itervalues():
countMap[v] = countMap.get(v,0) + 1
uni = [ k for k, v in a.iteritems() if countMap[v] == 1]
Here is a solution that only requires traversing the dict once:
def unique_values(d):
seen = {} # dict (value, key)
result = set() # keys with unique values
for k,v in d.iteritems():
if v in seen:
result.discard(seen[v])
else:
seen[v] = k
result.add(k)
return list(result)
Note that this actually is a bruteforce:
l = a.values()
b = [x for x in a if l.count(a[x]) == 1]
>>> b = []
>>> import collections
>>> bag = collections.defaultdict(lambda: 0)
>>> for v in a.itervalues():
... bag[v] += 1
...
>>> b = [k for (k, v) in a.iteritems() if bag[v] == 1]
>>> b.sort() # optional
>>> print b
['dog', 'snake']
>>>
A little more verbose, but does need only one pass over a:
revDict = {}
for k, v in a.iteritems():
if v in revDict:
revDict[v] = None
else:
revDict[v] = k
[ x for x in revDict.itervalues() if x != None ]
( I hope it works, since I can't test it here )
What about subclassing?
class UniqueValuesDict(dict):
def __init__(self, *args):
dict.__init__(self, *args)
self._inverse = {}
def __setitem__(self, key, value):
if value in self.values():
if value in self._inverse:
del self._inverse[value]
else:
self._inverse[value] = key
dict.__setitem__(self, key, value)
def unique_values(self):
return self._inverse.values()
a = UniqueValuesDict()
a['cat'] = 1
a['fish'] = 1
a[None] = 1
a['duck'] = 1
a['dog'] = 2 # <-- unique
a['bat'] = 3
a['aardvark'] = 3
a['snake'] = 4 # <-- unique
a['wallaby'] = 5
a['badger'] = 5
assert a.unique_values() == ['dog', 'snake']
Here's another variation.
>>> import collections
>>> inverse= collections.defaultdict(list)
>>> for k,v in a.items():
... inverse[v].append(k)
...
>>> [ v[0] for v in inverse.values() if len(v) == 1 ]
['dog', 'snake']
I'm partial to this because the inverted dictionary is such a common design pattern.
You could do something like this (just count the number of occurrences for each value):
def unique(a):
from collections import defaultdict
count = defaultdict(lambda: 0)
for k, v in a.iteritems():
count[v] += 1
for v, c in count.iteritems():
if c <= 1:
yield v
Use nested list comprehensions!
print [v[0] for v in
dict([(v, [k for k in a.keys() if a[k] == v])
for v in set(a.values())]).values()
if len(v) == 1]