Python Indexing - python

I have generated this following code first to calculate the frequencies of each element in the IDs list:
IDs =['fht142', 'fht142','fht178']
freqs = {}
for each in IDs:
freqs[each] = freqs.get(each, 0) + 1
print (each,freqs[each])
print (freqs)
so my freqs would look at this: {'fht178': 1, 'fht142': 2}
I just wonder how I could print out freqs as following:
fht178 1
fht142 2
many thx!!

data = {'fht178': 1, 'fht142': 2}
for k,v in data.iteritems():
print k,v
fht178 1
fht142 2

you can say:
for k, v in freqs.items():
print(k, v)

Related

Formatting dictionary entries

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

Python Compare Two Key/Value Pairs

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!

Problems with Python Dictionarys and nested Lists

I am trying to create a dictionary that has a nested list inside of it.
The goal would be to have it be:
key : [x,y,z]
I am pulling the information from a csv file and counting the number of times a certain key shows up in each column. However I am getting the below error
> d[key][i] = 1
KeyError: 'owner'
Where owner is the title of my column.
if __name__ == '__main__':
d = {}
with open ('sample.csv','r') as f:
reader = csv.reader(f)
for i in range(0,3):
for row in reader:
key = row[0]
if key in d:
d[key][i] +=1
else:
d[key][i] = 1
for key,value in d.iteritems():
print key,value
What do I tweak in this loop to have it create a key if it doesn't exist and then add to it if it does?
The problem is, that you try to use a list ([i]) where no list is.
So you have to replace
d[key][i] = 1
with
d[key] = [0,0,0]
d[key][i] = 1
This would first create the list with three entries (so you can use [0], [1] and [2] afterward without error) and then assigns one to the correct entry in the list.
You can use defaultdict:
from collections import defaultdict
ncols = 3
d = defaultdict(lambda: [0 for i in range(ncols)])
Use a try, catch block to append a list to the new key, then increment as needed
if __name__ == '__main__':
d = {}
with open ('sample.csv','r') as f:
reader = csv.reader(f)
for i in xrange(0,3):
for row in reader:
key = row[i]
try: d[key][i] += 1
except KeyError:
d[key] = [0, 0, 0]
d[key][i] = 1
for key,value in d.iteritems():
print key,value
Using defaultdict and Counter you can come up with a dict that allows you to easily measure how many times a key appeared in a position (in this case 1st, 2nd or 3rd, by the slice)
csv = [
['a','b','c','d'],
['e','f','g', 4 ],
['a','b','c','d']
]
from collections import Counter, defaultdict
d = defaultdict(Counter)
for row in csv:
for idx, value in enumerate(row[0:3]):
d[value][idx] += 1
example usage:
print d
print d['a'][0] #number of times 'a' has been found in the 1st position
print d['b'][2] #number of times 'b' found in the 3rd position
print d['f'][1] #number of times 'f' found in 2nd position
print [d['a'][n] for n in xrange(3)] # to match the format requested in your post
defaultdict(<class 'collections.Counter'>, {'a': Counter({0: 2}), 'c': Counter({2: 2}), 'b': Counter({1: 2}), 'e': Counter({0: 1}), 'g': Counter({2: 1}), 'f': Counter({1: 1})})
2
0
1
[2, 0, 0]
Or put into a function:
def occurrences(key):
return [d[key][n] for n in xrange(3)]
print occurrences('a') # [2, 0, 0]

dictionary values in python adding values

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

Number of different values assoicated with a key in a list of dicts

Given a list of dictionaries ( each of which have same keys), I want total number of different values with which a given key is associated
$ li = [{1:2,2:3},{1:2,2:4}] $ the expected output is {1:1,2:2}
I came up with the following piece of code...Is there a better way of doing this ?
counts = {}
values = {}
for i in li:
for key,item in i.items():
try:
if item in values[key]:
continue
except KeyError:
else:
try:
counts[key] += 1
except KeyError:
counts[key] = 1
try:
values[key].append(item)
except KeyError:
values[key] = [item]
Something like this is probably more direct:
from collections import defaultdict
counts = defaultdict(set)
for mydict in li:
for k, v in mydict.items():
counts[k].add(v)
That takes care of the collecting / counting of the values. To display them like you want them, this would get you there:
print dict((k, len(v)) for k, v in counts.items())
# prints {1: 1, 2: 2}
Here is yet another alternative:
from collections import defaultdict
counts = defaultdict(int)
for k, v in set(pair for d in li for pair in d.items()):
counts[k] += 1
And the result:
>>> counts
defaultdict(<type 'int'>, {1: 1, 2: 2})
You could so something like this:
li = [{1:2,2:3},{1:2,2:4}]
def makesets(x, y):
for k, v in x.iteritems():
v.add(y[k])
return x
distinctValues = reduce(makesets, li, dict((k, set()) for k in li[0].keys()))
counts = dict((k, len(v)) for k, v in distinctValues.iteritems())
print counts
When I run this it prints:
{1: 1, 2: 2}
which is the desired result.
counts = {}
values = {}
for i in li:
for key,item in i.items():
if not (key in values.keys()):
values[key] = set()
values[key].add(item)
for key in values.keys():
counts[key] = len(values[key])
using flattening list in case dicts are not alway same length:
li=[{1: 2, 2: 3}, {1: 2, 2: 4}, {1: 3}]
dic={}
for i,j in [item for sublist in li for item in sublist.items()]:
dic[i] = dic[i]+1 if i in dic else 1

Categories

Resources