By flybywire


2009-11-17 10:07:53 8 Comments

I like the Python list comprehension syntax.

Can it be used to create dictionaries too? For example, by iterating over pairs of keys and values:

mydict = {(k,v) for (k,v) in blah blah blah}  # doesn't work

12 comments

@fortran 2009-11-17 10:09:32

From Python 2.7 and 3 onwards, you should just use the dict comprehension syntax:

{key: value for (key, value) in iterable}

In Python 2.6 and earlier, the dict built-in can receive an iterable of key/value pairs, so you can pass it a list comprehension or generator expression. For example:

dict((key, func(key)) for key in keys)

However if you already have iterable(s) of keys and/or vals, you needn't use a comprehension at all - it's simplest just call the dict built-in directly:

# consumed from any iterable yielding pairs of keys/vals
dict(pairs)

# "zipped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))

@cryanbhu 2019-07-14 02:30:10

what if I have a case of list of words ['cat','dog','cat'] and I want to make a dict with key as word and value as count? Is there a short efficient syntax for that?

@fortran 2019-07-19 05:52:43

@cryanbhu if what you mean is to count the repetitions of a given element in the list, there's a Counter class in the collections package: docs.python.org/2/library/collections.html#collections.Count‌​er

@Amit Tripathi 2015-06-26 09:05:46

Python version < 2.7, do the below:

d = dict((i,True) for i in [1,2,3])

Python version >= 2.7, do the below:

d = {i: True for i in [1,2,3]}

@BERKO 2019-04-18 19:14:41

This code will create dictionary using list comprehension for multiple lists with different values that can be used for pd.DataFrame()

#Multiple lists 
model=['A', 'B', 'C', 'D']
launched=[1983,1984,1984,1984]
discontinued=[1986, 1985, 1984, 1986]

#Dictionary with list comprehension
keys=['model','launched','discontinued']
vals=[model, launched,discontinued]
data = {key:vals[n] for n, key in enumerate(keys)}

enumerate will pass n to vals to match each key with its list

@Aaron Hall 2017-01-03 21:57:11

Create a dictionary with list comprehension in Python

I like the Python list comprehension syntax.

Can it be used to create dictionaries too? For example, by iterating over pairs of keys and values:

mydict = {(k,v) for (k,v) in blah blah blah}

You're looking for the phrase "dict comprehension" - it's actually:

  mydict = {k:v  for k,v in iterable}

This is almost valid except for the blah blah blah:

mydict = {(k,v) for (k,v) in blah blah blah}
                                 ^^^^^^--invalid syntax

Assuming blah blah blah is an iterable of two-tuples - you're so close. Let's create some "blahs" like that:

blahs = [('blah0', 'blah'), ('blah1', 'blah'), ('blah2', 'blah'), ('blah3', 'blah')]

Dict comprehension syntax:

Now the syntax here is the mapping part. What makes this a dict comprehension instead of a set comprehension (which is what your pseudo-code approximates) is the colon, : like below:

mydict = {k: v for k, v in blahs}

And we see that it worked, and should retain insertion order as-of Python 3.7:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah2': 'blah', 'blah3': 'blah'}

In Python 2 and up to 3.6, order was not guaranteed:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah3': 'blah', 'blah2': 'blah'}

Adding a Filter:

All comprehensions feature a mapping component and a filtering component that you can provide with arbitrary expressions.

So you can add a filter part to the end:

>>> mydict = {k: v for k, v in blahs if not int(k[-1]) % 2}
>>> mydict
{'blah0': 'blah', 'blah2': 'blah'}

Here we are just testing for if the last character is divisible by 2 to filter out data before mapping the keys and values.

@Manikandan Kathir 2018-11-25 09:32:08

>>> {k: v**3 for (k, v) in zip(string.ascii_lowercase, range(26))}

Python supports dict comprehensions, which allow you to express the creation of dictionaries at runtime using a similarly concise syntax.

A dictionary comprehension takes the form {key: value for (key, value) in iterable}. This syntax was introduced in Python 3 and backported as far as Python 2.7, so you should be able to use it regardless of which version of Python you have installed.

A canonical example is taking two lists and creating a dictionary where the item at each position in the first list becomes a key and the item at the corresponding position in the second list becomes the value.

The zip function used inside this comprehension returns an iterator of tuples, where each element in the tuple is taken from the same position in each of the input iterables. In the example above, the returned iterator contains the tuples (“a”, 1), (“b”, 2), etc.

Output:

{'i': 512, 'e': 64, 'o': 2744, 'h': 343, 'l': 1331, 's': 5832, 'b': 1, 'w': 10648, 'c': 8, 'x': 12167, 'y': 13824, 't': 6859, 'p': 3375, 'd': 27, 'j': 729, 'a': 0, 'z': 15625, 'f': 125, 'q': 4096, 'u': 8000, 'n': 2197, 'm': 1728, 'r': 4913, 'k': 1000, 'g': 216, 'v': 9261}

@SilentGhost 2009-11-17 10:22:45

In Python 3 and Python 2.7+, dictionary comprehensions look like the below:

d = {k:v for k, v in iterable}

For Python 2.6 or earlier, see fortran's answer.

@Ekhtiar 2018-05-27 00:11:40

Just to throw in another example. Imagine you have the following list:

nums = [4,2,2,1,3]

and you want to turn it into a dict where the key is the index and value is the element in the list. You can do so with the following line of code:

{index:nums[index] for index in range(0,len(nums))}

@nomoreabond2017 2017-10-25 03:40:40

Here is another example of dictionary creation using dict comprehension:

What i am tring to do here is to create a alphabet dictionary where each pair; is the english letter and its corresponding position in english alphabet

>>> import string
>>> dict1 = {value: (int(key) + 1) for key, value in 
enumerate(list(string.ascii_lowercase))}
>>> dict1
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9, 'h': 8, 
'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17, 'p': 16, 's': 
19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25, 'x': 24, 'z': 26}
>>> 

Notice the use of enumerate here to get a list of alphabets and their indexes in the list and swapping the alphabets and indices to generate the key value pair for dictionary

Hope it gives a good idea of dictionary comp to you and encourages you to use it more often to make your code compact

@johnnydrama 2018-02-06 20:17:30

Nice answer - simplified: d = {k: v+1 for v, k in enumerate(string.ascii_lowercase)}

@Savad KP 2016-02-03 14:15:14

Try this,

def get_dic_from_two_lists(keys, values):
    return { keys[i] : values[i] for i in range(len(keys)) }

Assume we have two lists country and capital

country = ['India', 'Pakistan', 'China']
capital = ['New Delhi', 'Islamabad', 'Beijing']

Then create dictionary from the two lists:

print get_dic_from_two_lists(country, capital)

The output is like this,

{'Pakistan': 'Islamabad', 'China': 'Beijing', 'India': 'New Delhi'}

@Andre Simon 2016-10-16 15:24:02

you could have used zip

@Blairg23 2016-01-15 00:23:57

To add onto @fortran's answer, if you want to iterate over a list of keys key_list as well as a list of values value_list:

d = dict((key, value) for (key, value) in zip(key_list, value_list))

or

d = {(key, value) for (key, value) in zip(key_list, value_list)}

@Sphynx-HenryAY 2015-10-08 02:59:01

In Python 2.7, it goes like:

>>> list1, list2 = ['a', 'b', 'c'], [1,2,3]
>>> dict( zip( list1, list2))
{'a': 1, 'c': 3, 'b': 2}

Zip them!

@Jean-François Corbett 2017-02-09 17:37:21

This doesn't address the question at all.

@Sphynx-HenryAY 2019-03-13 04:50:31

@dexgecko my version is 3.6 and it didnt generate set at all, would you tell me wheres your set come from?

@dexgecko 2019-03-14 17:42:52

@Sphynx-HenryAY - I think I commented on the wrong answer.

@michaelmeyer 2013-05-31 17:48:45

In fact, you don't even need to iterate over the iterable if it already comprehends some kind of mapping, the dict constructor doing it graciously for you:

>>> ts = [(1, 2), (3, 4), (5, 6)]
>>> dict(ts)
{1: 2, 3: 4, 5: 6}
>>> gen = ((i, i+1) for i in range(1, 6, 2))
>>> gen
<generator object <genexpr> at 0xb7201c5c>
>>> dict(gen)
{1: 2, 3: 4, 5: 6}

Related Questions

Sponsored Content

41 Answered Questions

[SOLVED] How do I merge two dictionaries in a single expression?

60 Answered Questions

[SOLVED] How do you split a list into evenly sized chunks?

14 Answered Questions

[SOLVED] Add new keys to a dictionary?

16 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 3147837 View
  • 2683 Score
  • 16 Answer
  • Tags:   python dictionary

10 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

34 Answered Questions

[SOLVED] How do I sort a dictionary by value?

10 Answered Questions

[SOLVED] What is the difference between dict.items() and dict.iteritems()?

8 Answered Questions

[SOLVED] Python Dictionary Comprehension

5 Answered Questions

[SOLVED] Catch multiple exceptions in one line (except block)

191 Answered Questions

[SOLVED] Hidden features of Python

Sponsored Content