Consider I have a tuple in Python
numbers = (('One', 1), ('Two', 2), ('Three', 3), ('Four', 4))
I want to create a numbers_dict in dictionary
numbers_dict = {}
for number in numbers:
numbers_dict[number[0]] = number[1]
and so I get
numbers_dict = {
'One': 1,
'Two': 2,
'Three': 3,
'Four': 4,
}
Can I do something simpler using the syntax
numbers_dict = [n[0] : n[1] for n in numbers]
?
Just pass numbers directly to the dict() type:
numbers_dict = dict(numbers)
From the documentation:
If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value.
Your numbers tuple is such an iterable, and each element in it is a (key, value) pair.
Demo:
>>> numbers = (('One', 1), ('Two', 2), ('Three', 3), ('Four', 4))
>>> dict(numbers)
{'One': 1, 'Four': 4, 'Three': 3, 'Two': 2}
You could use a dictionary comprehension too, but that's really overkill here; only use that when you do something more meaningful for each key or value. But for completeness sake, that'd look like this:
numbers_dict = {k: v for k, v in numbers}
Related
In Python, suppose I want to grab N arbitrary items from a dictionary—say, to print them, to inspect a few items. I don't care which items I get. I don't want to turn the dictionary into a list (as does some code I have seen); that seems like a waste. I can do it with the following code (where N = 5), but it seems like there has to be a more Pythonic way:
count = 0
for item in my_dict.items():
if count >= 5:
break
print(item)
count += 1
Thanks in advance!
You can use itertools.islice to slice any iterable (not only lists):
>>> import itertools
>>> my_dict = {i: i for i in range(10)}
>>> list(itertools.islice(my_dict.items(), 5))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
I might use zip and range:
>>> my_dict = {i: i for i in range(10)}
>>> for _, item in zip(range(5), my_dict.items()):
... print(item)
...
(0, 0)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
The only purpose of the range here is to give an iterable that will cause zip to stop after 5 iterations.
You can modify what you have slightly:
for count, item in enumerate(dict.items()):
if count >= 5:
break
print(item)
Note: in this case when you're looping through .items(), you're getting a key/value pair, which can be unpacked as you iterate:
for count, (key, value) in enumerate(dict.items()):
if count >= 5:
break
print(f"{key=} {value=})
If you want just the keys, you can just iterate over the dict.
for count, key in enumerate(dict):
if count >= 5:
break
print(f"{key=})
If you want just the values:
for count, value in enumerate(dict.values()):
if count >= 5:
break
print(f"{value=})
And last note: using dict as a variable name overwrites the built in dict and makes it unavailable in your code.
Typically, I would like to use slice notation to do this, but dict.items() returns an iterator, which is not slicable.
You have two main options:
Make it something that slice notation works on:
x = {'a':1, 'b':2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
for item, index in list(x.items())[:5]:
print(item)
Use something that works on iterators. In this case, the built-in (and exceedingly popular) itertools package:
import itertools
x = {'a':1, 'b':2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
for item in itertools.islice(x.items(), 5):
print(item)
This question already has answers here:
How to keep keys/values in same order as declared?
(13 answers)
Closed 4 years ago.
I am reading a dictionary in python2.6 as below
I know Python3.6 will read the dictionary in the same order it is declared, but i need to achieve this in Python2.6 (OrderedDict is also not available in Python2.6)
numbermap = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
>>> for k, v in numbermap.iteritems():
... print(k,v)
...
('four', 4)
('three', 3)
('five', 5)
('two', 2)
('one', 1)
I want the output to be
('one',1)
('two', 2)
('three', 3)
('four', 4)
('five', 5)
I need to write as I read the dictionary. Any ideas to achieve this in Python 2.6?
There are many practices available for the sorting dictionary. You can check below examples.
First example:
>>> import operator
>>> numbermap = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
>>> sorted_maps = sorted(numbermap.items(), key=operator.itemgetter(1))
>>> print(sorted_maps)
[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
Second example:
>>> import collections
>>> sorted_maps = collections.OrderedDict(numbermap)
>>> print(sorted_maps)
OrderedDict([('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)])
It seems that you want an ordered dictionary. If you can use Python 2.7, look up collections.OrderedDict: https://docs.python.org/2/library/collections.html#collections.OrderedDict
If you have to stick with 2.6, there are some suggestions here: https://stackoverflow.com/a/1617087/3061818 (but you should probably head over to Dictionaries: How to keep keys/values in same order as declared?)
1 reverse the key value,
2 sort the new key which is the value
my solution is to sort the keys
sounds like cheating, but works:
first call something to reverse dict
for i in sort(numbermap.keys()):
print(i,numbermap[i])
This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed last month.
The only methods I found work for python2 or return only list of tuples.
Is it possible to sort dictionary, e.g. {"aa": 3, "bb": 4, "cc": 2, "dd": 1}, by its values?
Order of sorted dictionary I want to achieve is from largest to smallest. I want results to look like this:
bb 4
aa 3
cc 2
dd 1
And after sorting I want to store it into a text file.
itemgetter (see other answers) is (as I know) more efficient for large dictionaries but for the common case, I believe that d.get wins. And it does not require an extra import.
>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> for k in sorted(d, key=d.get, reverse=True):
... k, d[k]
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)
Note that alternatively you can set d.__getitem__ as key function which may provide a small performance boost over d.get.
from collections import OrderedDict
from operator import itemgetter
d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))
prints
OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])
Though from your last sentence, it appears that a list of tuples would work just fine, e.g.
from operator import itemgetter
d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
print(key, value)
which prints
bb 4
aa 3
cc 2
dd 1
You can sort by values in reverse order (largest to smallest) using a dictionary comprehension:
{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}
If you want to sort by values in ascending order (smallest to largest)
{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}
If you want to sort by the keys in ascending order
{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}
This works on CPython 3.6+ and any implementation of Python 3.7+ because dictionaries keep insertion order.
Another way is to use a lambda expression. Depending on interpreter version and whether you wish to create a sorted dictionary or sorted key-value tuples (as the OP does), this may even be faster than the accepted answer.
d = {'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1}
s = sorted(d.items(), key=lambda x: x[1], reverse=True)
for k, v in s:
print(k, v)
To sort dictionary, we could make use of operator module. Here is the operator module documentation.
import operator #Importing operator module
dc = {"aa": 3, "bb": 4, "cc": 2, "dd": 1} #Dictionary to be sorted
dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort
Output sequence will be a sorted list :
[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]
If we want to sort with respect to keys, we can make use of
dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)
Output sequence will be :
[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
To sort a dictionary and keep it functioning as a dictionary afterwards, you could use OrderedDict from the standard library.
If that's not what you need, then I encourage you to reconsider the sort functions that leave you with a list of tuples. What output did you want, if not an ordered list of key-value pairs (tuples)?
I'm trying to convert a list to a dictionary by using the dict function.
inpu = input.split(",")
dic = dict(inpu)
The above code is trying to get a string and split it on ',' and afterwards I use the dict function to convert the list to a dictionary.
However, I get this error:
ValueError: dictionary update sequence element #0 has length 6; 2 is required
Can anybody help?
dict expects an iterable of 2-element containers (like a list of tuples). You can't just pass a list of items, it doesn't know what's a key and what's a value.
You are trying to do this:
>>> range(10)
<<< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> dict(range(10))
---------------------------------------------------------------------------
TypeError: cannot convert dictionary update sequence element #0 to a sequence
dict expects a list like this:
>>> zip(lowercase[:5], range(5))
<<<
[('a', 0),
('b', 1),
('c', 2),
('d', 3),
('e', 4)]
The first element in the tuple becomes the key, the second becomes the value.
>>> dict(zip(lowercase[:5], range(5)))
<<<
{'a': 0,
'b': 1,
'c': 2,
'd': 3,
'e': 4}
As listed on the Python Data structures Docs. The dict() constructor builds dictionaries directly from lists of key-value pairs stored as tuples.
so the inpu array must be of form ('key', 'value') at each position, for example
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
your input array is probably greater than 2 in size
A dictionary is a key-value pair which is why it says length-2 lists are needed to match keys to values. You are splitting the input into a flat list, which is why Python is complaining in this case - it doesn't know what to specify as keys and what to specify as values.
I have been poking around for a recipe / example to index a list of tuples without taking a modification of the decorate, sort, undecorate approach.
For example:
l=[(a,b,c),(x,c,b),(z,c,b),(z,c,d),(a,d,d),(x,d,c) . . .]
The approach I have been using is to build a dictionary using defaultdict of the second element
from collections import defaultdict
tdict=defaultdict(int)
for myTuple in l:
tdict[myTuple[1]]+=1
Then I have to build a list consisting of only the second item in the tuple for each item in the list. While there are a number of ways to get there a simple approach is to:
tempList=[myTuple[1] for myTuple in l]
and then generate an index of each item in tdict
indexDict=defaultdict(dict)
for key in tdict:
indexDict[key]['index']=tempList.index(key)
Clearly this does not seem very Pythonic. I have been trying to find examples or insights thinking that I should be able to use something magical to get the index directly. No such luck so far.
Note, I understand that I can take my approach a little more directly and not generating tdict.
output could be a dictionary with the index
indexDict={'b':{'index':0},'c':{'index':1},'d':{'index':4},. . .}
After learning a lot from Nadia's responses I think the answer is no.
While her response works I think it is more complicated than needed. I would simply
def build_index(someList):
indexDict={}
for item in enumerate(someList):
if item[1][1] not in indexDict:
indexDict[item[1][1]]=item[0]
return indexDict
This will generate the result you want
dict((myTuple[1], index) for index, myTuple in enumerate(l))
>>> l = [(1, 2, 3), (4, 5, 6), (1, 4, 6)]
>>> dict((myTuple[1], index) for index, myTuple in enumerate(l))
{2: 0, 4: 2, 5: 1}
And if you insist on using a dictionary to represent the index:
dict((myTuple[1], {'index': index}) for index, myTuple in enumerate(l))
The result will be:
{2: {'index': 0}, 4: {'index': 2}, 5: {'index': 1}}
EDIT
If you want to handle key collision then you'll have to extend the solution like this:
def build_index(l):
indexes = [(myTuple[1], index) for index, myTuple in enumerate(l)]
d = {}
for e, index in indexes:
d[e] = min(index, d.get(e, index))
return d
>>> l = [(1, 2, 3), (4, 5, 6), (1, 4, 6), (2, 4, 6)]
>>> build_index(l)
{2: 0, 4: 2, 5: 1}
EDIT 2
And a more generalized and compact solution (in a similar definition to sorted)
def index(l, key):
d = {}
for index, myTuple in enumerate(l):
d[key(myTuple)] = min(index, d.get(key(myTuple), index))
return d
>>> index(l, lambda a: a[1])
{2: 0, 4: 2, 5: 1}
So the answer to your question is yes: There is a way in Python to index a list of containers (tuples, lists, dictionaries) by an element of a container without preprocessing. But your request of storing the result in a dictionary makes it impossible to be a one liner. But there is no preprocessing here. The list is iterated only once.
If i think this is what you're asking...
l = ['asd', 'asdxzc']
d = {}
for i, x in enumerate(l):
d[x] = {'index': i}