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!
Related
I'm running python 2.7 in PS on a w10. I want to print the key and the value of a dictionary with every pair enumerated.
I do the following:
my_dict = {'key_one': 1, 'key_two': 2, 'key_three': 3}
for k, v in enumerate(my_dict.iteritems(), start = 1):
print k, v
which in turn gives:
1 ('key_one', 1)
2 ('key_two', 2)
3 ('key_three', 3)
How do I return the entries without the braces?
Example - I want to put a = sign in between my key-value pairs.
If you want to keep the indicies (from enumerate), then you're going to have to unpack the key and value from the dict items separates. Right now what you're calling k is actually an index, and what you're calling v is actually a key-value pair. Try something like this:
for i, (k, v) in enumerate(my_dict.iteritems(), start=1):
print i, k, v
That results in something like:
1 key_two 2
2 key_one 1
3 key_three 3
To get them formatted with an equals sign, you'd have to change the print statement to print i, "{}={}".format(k, v), which would result in something like:
1 key_two=2
2 key_one=1
3 key_three=3
If you need to retrieve the keys in a consistent order, use sorted(), like this:
for i, (k, v) in enumerate(sorted(my_dict.iteritems()), start=1):
...
Or, if you want to sort by values first instead of the keys first, you could specify a key function for the sorted() call. That would look like: sorted(my_dict.iteritems(), key=lambda (x, y): (y, x)). That would give you an output of
1 key_one=1
2 key_two=2
3 key_three=3
You don't need enumerate if you just want to print the existing key and values in your dictionary. Just use format():
for k, v in my_dict.items():
print '{} = {}'.format(k, v)
This would give:
key_one = 1
key_two = 2
key_three = 3
This works
my_dict = {'key_one': 1, 'key_two': 2, 'key_three': 3}
for key,value in my_dict.iteritems():
print key,value
Like this?
>>> for k, v in my_dict.iteritems():
... print k, v
...
key_two 2
key_one 1
key_three 3
or
>>> for i, (k, v) in enumerate(my_dict.iteritems(), start=1):
... print i, k, v
...
1 key_two 2
2 key_one 1
3 key_three 3
Simple one-line solution(for Python 2.7):
print '\n'.join([k+'='+ str(my_dict[k]) for k in my_dict.keys()])
The output:
key_two=2
key_one=1
key_three=3
You do not need enumerate() here. It is used when you need to iterate along with the index. you do not even need str.format() for achieving this. Simply place a entry of '=' string between your key, value and you will get what your desire. For example:
>>> my_dict = {'key_one': 1, 'key_two': 2, 'key_three': 3}
>>> for key, value in my_dict.items():
... print key, '=', value
...
key_two = 2
key_one = 1
key_three = 3
Edit: Based on the comment at user3030010's answer
Note: dict in python are un ordered. In case you want to maintain the order, use collections.OrderedDict() instead. It will preserve the order independent of the platform and python version. For example if you created the dict like:
>>> from collections import OrderedDict
>>> my_dict = OrderedDict()
>>> my_dict['key_one'] = 1
>>> my_dict['key_two'] = 2
>>> my_dict['key_three'] = 3
On iterating it, you will always get the same response as:
>>> for key, value in my_dict.items():
... print key, '=', value
...
key_one = 1
key_two = 2
key_three = 3
I'm trying to count the number of times a specified key occurs in my list of dicts. I've used Counter() and most_common(n) to count up all the keys, but how can I find the count for a specific key? I have this code, which does not work currently:
def Artist_Stats(self, artist_pick):
entries = TopData(self.filename).data_to_dict()
for d in entries:
x = d['artist']
find_artist = Counter()
print find_artist[x][artist_pick]
The "entries" data has about 60k entries and looks like this:
[{'album': 'Nikki Nack', 'song': 'Find a New Way', 'datetime': '2014-12-03 09:08:00', 'artist': 'tUnE-yArDs'},]
You could extract it, put it into a list, and calculate the list's length.
key_artists = [k['artist'] for k in entries if k.get('artist')]
len(key_artists)
Edit: using a generator expression might be better if your data is big:
key_artists = (1 for k in entries if k.get('artist'))
sum(key_artists)
2nd Edit:
for a specific artist, you would replace if k.get('artist') with if k.get('artist') == artist_pick
3rd Edit: you could loop as well, if you're not comfortable with comprehensions or generators, or if you feel that enhances code readability
n = 0 # number of artists
for k in entries:
n += 1 if k.get('artist') == artist_pick else 0
You can add Counter objects together with +. Below is a demonstration:
>>> from collections import Counter
>>> data = [{'a':1, 'b':1}, {'a':1, 'c':1}, {'b':1, 'c':1}, {'a':1, 'c':1}, {'a':1, 'd':1}]
>>> counter = Counter(data[0])
>>> for d in data[1:]:
... counter += Counter(d)
...
>>> counter
Counter({'a': 4, 'c': 3, 'b': 2, 'd': 1})
>>> counter['a'] # Count of 'a' key
4
>>> counter['d'] # Count of 'd' key
1
>>>
Or, if you want to get fancy, replace the for-loop with sum and a generator expression:
>>> from collections import Counter
>>> data = [{'a':1, 'b':1}, {'a':1, 'c':1}, {'b':1, 'c':1}, {'a':1, 'c':1}, {'a':1, 'd':1}]
>>> counter = sum((Counter(d) for d in data[1:]), Counter(data[0]))
>>> counter
Counter({'a': 4, 'c': 3, 'b': 2, 'd': 1})
>>>
I personally prefer the readability of the for-loop though.
If you mean to count the keys rather than the distinct values to a particular key, then without Counter():
artist_key_count = 0
for track in entries:
if 'artist' in track.keys():
artist_key_count += 1
If you mean to count the number of times each artist appears in your list of tracks, you can also do this without Counter():
artist_counts = {}
for track in entries:
artist = track.get('artist')
try:
artist_counts[artist] += 1
except KeyError:
artist_counts[artist] = 1
I look for something that will count values in dict (automatically)without use a list of element
d = {}
d["x1"] = "1"
{'x1':'1'}
d["x1"] = "2"
{'x1':'2'}
d["x1"] = "3"
{'x1':'3'}
d["x2"] = "1"
{'x1':'3', 'x2':'1'}
ect..
I try create a list them using
for x in list:
d[x] = list.count(x)
But when I created a list , I receive a memory error
Are you sure you want to use a dict to do it? It seems a Counter or a defaultdict suits your need more.
>>> d = collections.Counter()
>>> d['x1'] += 1
>>> d
Counter({'x1': 1})
>>> d['x1'] += 1
>>> d
Counter({'x1': 2})
>>> d['x2'] += 1
>>> d
Counter({'x1': 2, 'x2': 1})
You could also convert a sequence to a counter:
>>> collections.Counter(['x1', 'x1', 'x2'])
Counter({'x1': 2, 'x2': 1})
Use a defaultdict:
>>> d = defaultdict(int)
>>> d['foo'] += 1
>>> d['foo'] += 1
>>> d['bar'] += 1
>>> for i in d:
... print i,d[i]
...
foo 2
bar 1
You can use dict in the following manner -
d['x1'] = d.get('x1', 0) + 1
The second argument in get specifies the object to return if the key supplied in the first argument is not found.
Applying this on your example:
from pprint import pprint
d = {}
d['x1'] = d.get('x1', 0) + 1
d['x1'] = d.get('x1', 0) + 1
d['x1'] = d.get('x1', 0) + 1
d['x2'] = d.get('x2', 0) + 1
pprint(d) # will print {'x1': 3, 'x2': 1}
So here is my problem, i have a dictionary with following key => values:
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002:политичка -> 2
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002:државата -> 2
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002:енергично -> 1
1caa60ebf9459d9cd406f1a03e1719b675dcfaad78292edc7e4a56be:полициска -> 1
I have this code to show the keys needed:
for key, value in count_db.iteritems():
print key[:56]
So now i have:
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002 -> 2
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002 -> 2
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002 -> 1
1caa60ebf9459d9cd406f1a03e1719b675dcfaad78292edc7e4a56be -> 1
I need to merge them into:
6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002 -> 5
1caa60ebf9459d9cd406f1a03e1719b675dcfaad78292edc7e4a56be -> 1
I have made this but i have not succeed in doing it correctly:
length_dic=len(count_db.keys())
for key, value in count_db.iteritems():
count_element=key[:56]
#print "%s => %s" % (key[:56], value) #value[:56]
for i in range(length_dic):
i+=1
if count_element == key[:56]:
itr+=int(value)
print i
length_dic=length_dic-1
Any hints?
A trivial approach would be:
result = {}
for key, value in count_db.iteritems():
result[key[:56]] = result.get(key[:56], 0) + value
You could also achieve the same with reduce if you want to get it on one line:
import collections
result = reduce(lambda x,y: x[y[0][:56]] += y[1] , count_db.iteritems(), collections.defaultdict(int))
Given your dictionary as
>>> spam={"6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002:AAAA": 2,
"6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002:BBBB": 2,
"6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002:CCCC": 1,
"1caa60ebf9459d9cd406f1a03e1719b675dcfaad78292edc7e4a56be:DDDD": 1
}
you can somewhat do like the following
>>> bacon=collections.defaultdict(int)
>>> for k,v in [(k[:56],v) for k,v in spam.iteritems()]:
bacon[k]+=v
>>> bacon
defaultdict(<type 'int'>, {'6bc51fb21fd9eefef4ec97a241733cd59b71e8e14ad70e9068d32002': 5, '1caa60ebf9459d9cd406f1a03e1719b675dcfaad78292edc7e4a56be': 1})
>>>
This is exactly what the Counter object (in version 2.7+) is for:
import collections
c = collections.Counter()
for key, value in count_db.iteritems():
c[key[:56]] += value
I didn't understand why you did all that in your code. I think this would do the job:
tmp_dict = {}
for key, value in count_db.iteritems():
count_element=key[:56]
if count_element in tmp_dict:
tmp_dict[count_element] += value
else:
tmp_dict[count_element] = value
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]