enumerate() for dictionary in Python - python

I know we use enumerate for iterating a list but I tried it on a dictionary and it didn't give an error.
CODE:
enumm = {0: 1, 1: 2, 2: 3, 4: 4, 5: 5, 6: 6, 7: 7}
for i, key in enumerate(enumm):
print(i, key)
OUTPUT:
0 0
1 1
2 2
3 4
4 5
5 6
6 7
Can someone please explain the output?

On top of the already provided answers there is a very nice pattern in Python that allows you to enumerate both keys and values of a dictionary.
The normal case you enumerate the keys of the dictionary:
example_dict = {1:'a', 2:'b', 3:'c', 4:'d'}
for i, k in enumerate(example_dict):
print(i, k)
Which outputs:
0 1
1 2
2 3
3 4
But if you want to enumerate through both keys and values this is the way:
for i, (k, v) in enumerate(example_dict.items()):
print(i, k, v)
Which outputs:
0 1 a
1 2 b
2 3 c
3 4 d

The first column of output is the index of each item in enumm and the second one is its keys. If you want to iterate your dictionary then use .items():
for k, v in enumm.items():
print(k, v)
And the output should look like:
0 1
1 2
2 3
4 4
5 5
6 6
7 7

Just thought I'd add, if you'd like to enumerate over the index, key, and values of a dictionary, your for loop should look like this:
for index, (key, value) in enumerate(your_dict.items()):
print(index, key, value)

dict1={'a':1, 'b':'banana'}
To list the dictionary in Python 2.x:
for k,v in dict1.iteritems():
print k,v
In Python 3.x use:
for k,v in dict1.items():
print(k,v)
# a 1
# b banana
Finally, as others have indicated, if you want a running index, you can have that too:
for i in enumerate(dict1.items()):
print(i)
# (0, ('a', 1))
# (1, ('b', 'banana'))
But this defeats the purpose of a dictionary (map, associative array) , which is an efficient data structure for telephone-book-style look-up. Dictionary ordering could be incidental to the implementation and should not be relied upon. If you need the order, use OrderedDict instead.

enumerate() when working on list actually gives the index and the value of the items inside the list.
For example:
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i, j in enumerate(list):
print(i, j)
gives
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
where the first column denotes the index of the item and 2nd column denotes the items itself.
In a dictionary
enumm = {0: 1, 1: 2, 2: 3, 4: 4, 5: 5, 6: 6, 7: 7}
for i, j in enumerate(enumm):
print(i, j)
it gives the output
0 0
1 1
2 2
3 4
4 5
5 6
6 7
where the first column gives the index of the key:value pairs and the second column denotes the keys of the dictionary enumm.
So if you want the first column to be the keys and second columns as values, better try out dict.iteritems()(Python 2) or dict.items() (Python 3)
for i, j in enumm.items():
print(i, j)
output
0 1
1 2
2 3
4 4
5 5
6 6
7 7
Voila

Since you are using enumerate hence your i is actually the index of the key rather than the key itself.
So, you are getting 3 in the first column of the row 3 4even though there is no key 3.
enumerate iterates through a data structure(be it list or a dictionary) while also providing the current iteration number.
Hence, the columns here are the iteration number followed by the key in dictionary enum
Others Solutions have already shown how to iterate over key and value pair so I won't repeat the same in mine.

Iterating over a Python dict means to iterate over its keys exactly the same way as with dict.keys()
The order of the keys is determined by the implementation code and you cannot expect some specific order:
Keys and values are iterated over in an arbitrary order which is
non-random, varies across Python implementations, and depends on the
dictionary’s history of insertions and deletions. If keys, values and
items views are iterated over with no intervening modifications to the
dictionary, the order of items will directly correspond.
That's why you see the indices 0 to 7 in the first column. They are produced by enumerate and are always in the correct order. Further you see the dict's keys 0 to 7 in the second column. They are not sorted.

That sure must seem confusing. So this is what is going on. The first value of enumerate (in this case i) returns the next index value starting at 0 so 0, 1, 2, 3, ... It will always return these numbers regardless of what is in the dictionary. The second value of enumerate (in this case j) is returning the values in your dictionary/enumm (we call it a dictionary in Python). What you really want to do is what roadrunner66 responded with.

Python3:
One solution:
enumm = {0: 1, 1: 2, 2: 3, 4: 4, 5: 5, 6: 6, 7: 7}
for i, k in enumerate(enumm):
print("{}) d.key={}, d.value={}".format(i, k, enumm[k]))
Output:
0) enumm.key=0, enumm.value=1
1) enumm.key=1, enumm.value=2
2) enumm.key=2, enumm.value=3
3) enumm.key=4, enumm.value=4
4) enumm.key=5, enumm.value=5
5) enumm.key=6, enumm.value=6
6) enumm.key=7, enumm.value=7
An another example:
d = {1 : {'a': 1, 'b' : 2, 'c' : 3},
2 : {'a': 10, 'b' : 20, 'c' : 30}
}
for i, k in enumerate(d):
print("{}) key={}, value={}".format(i, k, d[k])
Output:
0) key=1, value={'a': 1, 'b': 2, 'c': 3}
1) key=2, value={'a': 10, 'b': 20, 'c': 30}

You may find it useful to include index inside key:
d = {'a': 1, 'b': 2}
d = {(i, k): v for i, (k, v) in enumerate(d.items())}
Output:
{(0, 'a'): True, (1, 'b'): False}

d = {0: 'zero', '0': 'ZERO', 1: 'one', '1': 'ONE'}
print("List of enumerated d= ", list(enumerate(d.items())))
output:
List of enumerated d= [(0, (0, 'zero')), (1, ('0', 'ZERO')), (2, (1, 'one')), (3, ('1', 'ONE'))]

Related

How do I sort with multiple conditions on python?

6 7 5 2 12
0 2 3 6 12
2 8 5 4 13
4 3 5 7 14
def getMinIndex(list, start, stop):
n=len(list)
min_index = start
for i in range(start,stop):
if list[i][4] > myList[min_index][4]:
min_index = i
return min_index
def swapElements(list,i,j):
temp = list[i]
list[i] = list[j]
list[j] = temp
With this code I manage to sort the last element on the list which is index 4 but I'm having problem to sort the 1st index as I want the results to be like this.
0 2 3 6 12
6 7 5 2 12
2 8 5 4 13
4 3 5 7 14
So if the last element is the same after sorting then I want to sort the 1st element. Can anyone help? Thanks :D
What you're looking for is a key function for items on your list. Let me illustrate with an example.
Sorting keys
Suppose you have a list of people. You want to sort them by height. You can't just sort them using sorted because they aren't comparable by default the way numbers are. You need to specify the key used for sorting. The key is the characteristic you want to sort on. In this case it could look like:
sorted(people, key=lambda person: person.height)
or, if you find the lambda notation confusing:
def get_height(person):
return person.height
sorted(people, key=get_height)
Sorting tuples
A tuple is a finite sequence of items: (2,3) (2-tuple or pair), (-3, 2, 1) (3-tuple) and so on. Tuples are sorted alphabetically automatically. You don't need to do anything.
What's special in your case is that you don't want to sort by the first element, then by the second, and so on. You want to sort by the fourth and then by the first.
This is where keys enter the scene.
Tying it all together
You need a key function that will turn (a, b, c, d, e) into (e, a) which means: sort by the fifth column first and then by the first one:
def sorting_key(item):
return (item[4], item[0])
Then you can just call:
sorted(items, key=sorting_key)
# or with a lambda
sorted(items, key=lambda item: (item[4], item[0]))
Getting the index corresponding to a minimum
I noticed that your function returns a minimum corresponding to the element. You can sort the whole thing and take the first element. Alternatively, you can use the built-in min function and provide it the sorting key.
The only thing you need to take into account is that min returns the corresponding value, not the index. You can work around this with:
min_index, min_value = min(enumerate(items), key=lambda (index, value): (value[4], value[0]))
enumerate pairs list items with their indexes so [a, b, c] becomes [(0, a), (1, b), (2, c)]. Then you sort these pairs as if the indexes weren't present: key accepts index as the first argument in a tuple but ignores it completely.
You can use operator.itemgetter and use it for a custom sorting key function which you can pass to one of the built-in sort functions:
> from operator import itemgetter
> lst = [
[2, 8, 5, 4, 13],
[6, 7, 5, 2, 12],
[4, 3, 5, 7, 14],
[0, 2, 3, 6, 12]
]
# use tuple of last and first elmnt as sorting key
> sorted(lst, key=itemgetter(-1, 0))
[
[0, 2, 3, 6, 12],
[6, 7, 5, 2, 12],
[2, 8, 5, 4, 13],
[4, 3, 5, 7, 14]
]

How to delete single value in a loop over dict?

I'd like to iterate over a dict with for loop in range of 3 and delete the first 3 values not keys from that dict.
d = {'dec': (8, 12, 7, 5, 3)}
for items, rang in zip(sorted(d.items(), reverse=True), range(3)):
.... ?
It is not clear what you are asking, but do you mean you want to remove the first three items in the tuple d['dec'] == (8, 12, 7, 5, 3) (i.e. 8, 12 and 7)? If so:
>>> d = {'dec': (8, 12, 7, 5, 3)}
>>> d['dec'] = d['dec'][3:]
>>> d
{'dec': (5, 3)}
In your example, your code pulls the whole d dict_items (('dec', (8,12,7,5,3))) and zips it up with the number zero (0) which is the first number from the range generator. It assigns that d dict_items to items, and the number zero to rang.
I don't think that's what you're trying to do, I think you're trying to sort the dictionaries by month, then remove the first three values from each month, is that right?
If so:
monthorder = ['jan','feb','mar','apr','may','jun','jul','aug','sept','oct','nov','dec']
d = {'dec': (8,12,7,5,3), ... } # I'm assuming this has more than one key
count = 0
for key, values in sorted(d.items(), key=lambda x: monthorder.index(x[0])):
d[key] = values[3:]
count += 1
if count == 3: break

User List to Remove keys from Dictionary

What is the best way to get a user to be able to enter a list(or singular) number to remove a string key entry from a dictionary?
so far this is where I am.
My dictionary to remove the values from(the dictionary is generated so will vary).
d = {'Seven': 22, 'Six': 0, 'Three': 35, 'Two': 0, 'Four': 45, 'Five': 34, 'Eight': 0}
1) So how do I get the input is my first query. This was my attempt but failed.
>>> s = raw_input('1 2 3 4')
1 2 3 4
>>> numbers = map(str, s.split())
>>> numbers
[]
>>> s = raw_input('1 2 3 4')
1 2 3 4
>>> numbers = map(int, s.split())
>>> numbers
[]
2) How would I convert the ints to word form? Here the range is limited there will never be greater than 20 entries per dictionary.
So my initial thought was to create a key of sorts to interpret the info.
e = {'One': 1, 'Two': 2, 'Three': 3, 'Four': 4}
and this works not as expected removing only one entry.
>>> e = {'One': 1, 'Two': 2, 'Three': 3, 'Four': 4}
>>> {k:v for k,v in e.items() if v!=(1 and 3)}
{'Four': 4, 'Two': 2, 'One': 1}
My intention is to remove the values from d and not e. Its also not practical as I don't know how many entries the user will enter so using 'and' statements seems wrong.
First, the parameters of raw_input are just for display. You need to enter it yourself:
>>> s = raw_input("Enter a sequence of number: ")
Enter a sequence of number: 1 2 3 4
>>> print s
1 2 3 4
Now, you can just use a list to map it:
m = ['1':'One', '2':'Two', '3':'Three', .., '10':'Ten']
Edit Here is how to convert it:
e = [v for k, v in m.items() if k in s]
Third, dictionary comprehensions (or 'comprehensions' in general) weren't meant to modify an existing object, but to create a new one. The closest you can get is to make it act like a filter, and reassign the results back to d
d = {k:v for k, v in d.items() if k not in e}

Multi dictionary - convert keys of dictionary to numbers

I have the following multi-dictionary which get output from a file and in my script, its taken as standard input:
{ 345 : {'name': 5, 'count': 6, 'top': 0} }
{ 233 : {'name': 6, 'count': 4, 'top': 0} }
{ 123 : {'name': 2, 'count': 9, 'top': 1} }
I want to convert all the keys of the dictionary to numbers like this:
{ 1 : {'1': 5, '2': 6, '3': 0} }
{ 2 : {'1': 6, '2': 4, '3': 0} }
{ 3 : {'1': 2, '2': 9, '3': 1} }
Output of the file should be:
1 1: 5 2: 6 3: 0
2 1: 6 2: 4 3: 0
3 1: 2 2: 9 3: 1
I am trying to understand dictionaries and new to python so wondering how I can achieve it.
Here is my code
for line in sys.stdin:
d = ast.literal_eval(line)
for k,v in d.items():
inner_dict = dicts.setdefault(k, {})
inner_dict= dict((t,i) for (t,i) in enumerate(sorted(dicts.keys())))
for key, value in inner_dict.items():
print key, value
The above code gives me the following output but does not give me what I want.
0 123
1 233
2 345
Where am I going wrong.
Produce dictionaries as specified in the example:
# generate individual converted dictionaries
# not tested with sys.stdin
def gen_with_appropriate_name():
for n, line in enumerate(sys.stdin, 1):
d = ast.literal_eval(line)
sub_d = d.values()[0]
yield {n : {'1' : sub_d['name'],
'2' : sub_d['count'],
'3' : sub_d['top']}}
The following will produce a similar result with the enumeration of the sub dictionary based on its original keys, sorted.
# generate individual converted dictionaries
# not tested with sys.stdin
def gen_with_appropriate_name():
for n, line in enumerate(sys.stdin, 1):
d = ast.literal_eval(line)
items = d.values()[0].items()
items.sort(key = lambda itm: itm[0])
yield {n: {i+1:item[1] for i, item in enumerate(items)}}
Usage -with printout in format specified
d = gen_with_appropriate_name()
for thing in d:
first = str(thing.keys()[0])
second = thing.values()[0]
print first + ' ' + ' '.join('{}: {}'.format(*item) for item in second.iteritems())
Output using the first function:
1 1: 5 3: 0 2: 6
2 1: 6 3: 0 2: 4
3 1: 2 3: 1 2: 9
Output using second function
1 1: 6 2: 5 3: 0
2 1: 4 2: 6 3: 0
3 1: 9 2: 2 3: 1
Explanation:
gen_with appropriate_name()
This function gets data from sys.stdin one line at a time and generates a dictionary for each of those lines in turn. It is iterable. http://docs.python.org/2.7/glossary.html#term-iterable
yield {n: {i+1:item[1] for i, item in enumerate(items)}}
The yield statement makes the function a generator. The function is suspended at the yield statement until next() is called, then execution resumes til another yield statement is encountered. A generator's next() method returns the value of the yield statement's expression list.
http://docs.python.org/2.7/reference/expressions.html#yieldexpr
{n: {i+1:item[1] for i, item in enumerate(items)}}
This is the yield statement's expression list. It creates a dictionary with n as the key. The value is a dictionary created with a dictionary display which is similar to a list comprehension.
http://docs.python.org/2.7/reference/expressions.html#displays-for-sets-and-dic‌​tionaries

Python Sorted by Index

Lets say there is a dictionary
foo = {'b': 1, 'c':2, 'a':3 }
I want to iterate over this dictionary in the order of the appearance of items in the dictionary.
for k,v in foo.items():
print k, v
prints
a 3
c 2
b 1
If we use sorted() function:
for k,v in sorted(foo.items()):
print k, v
prints
a 3
b 1
c 2
But i need them in the order in which they appear in the dictionary i;e
b 1
c 2
a 3
How do i achieve this ?
Dictionaries have no order. If you want to do that, you need to find some method of sorting in your original list. Or, save the keys in a list in the order they are saved and then access the dictionary using those as keys.
From The Python Docs
It is best to think of a dictionary as an unordered set of key: value
pairs, with the requirement that the keys are unique (within one
dictionary).
Example -
>>> testList = ['a', 'c', 'b']
>>> testDict = {'a' : 1, 'c' : 2, 'b' : 3}
>>> for elem in testList:
print elem, testDict[elem]
a 1
c 2
b 3
Or better yet, use an OrderedDict -
>>> from collections import OrderedDict
>>> testDict = OrderedDict([('a', 1), ('c', 2), ('b', 3)])
>>> for key, value in testDict.items():
print key, value
a 1
c 2
b 3
Maybe this?
sorted(foo, key=foo.get)
If you want to use your OrderedDict multiple times, use an OrderedDict like people have said. :) If you just want a one-liner for a one-off, change your sort function:
sorted(foo.items(), lambda a,b:a[1]-b[1])
You can do this by one-liner:
>>> sorted(foo.items(), key=lambda x: x[1])
[('b', 1), ('c', 2), ('a', 3)]
An ordered dictionary would have to be used to remember the order that they were stored in
>>>from collections import OrderedDict
>>>od = OrderedDict()
>>>od['b'] = 1
>>>od['c'] = 2
>>>od['a'] = 3
>>>print od
OrderedDict([('b',1), ('c',2), ('a',3)]
The see this more directly, the order you used to create the dict is not the order of the dict. The order is indeterminate.
>>> {'b': 1, 'c':2, 'a':3 }
{'a': 3, 'c': 2, 'b': 1}
If you just want to sort them by the keys do:
sorted_by_keys_dict = dict((y,x) for x,y in foo.iteritems())
for k,v in sorted(sorted_by_keys_dict.items()):
print v, k
a 1
c 2
b 3
or simply:
for k,v in sorted(dict((y,x) for x,y in foo.iteritems()).items()):
print v, k
a 1
c 2
b 3

Categories