Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python oneliner to initialize a dictionary [duplicate]

I am looking for a short and compact one-liner to initialize a dictionary from a list in Python. Is there an equivalent to the two constructs below?

dic = {}
for elt in list:
  dic[elt.hash] = elt

.

dic2 = {}
defaultValue = 0
for elt in list:
  dic2[elt] = defaultValue

I've see the use of Counter for the second case, but it is a very narrow case, and I'm looking for a generic syntax.

like image 904
PPC Avatar asked Dec 18 '22 01:12

PPC


2 Answers

Summary of three pythonic solutions to instantiating dictionaries. Having a "one-line" solution should never be the most important consideration.

1. Keys and default value defined in advance.

Instead of setting a default value for every key, use dict.fromkeys. Also, do not name variables the same as classes, e.g. use lst instead.

dic2 = dict.fromkeys(lst, 0)

2. Default value defined in advance, but not keys.

Alternatively, if you will be adding more keys in the future, consider using collections.defaultdict, which is a subclass of dict:

from collections import defaultdict
dic2 = defaultdict(int)
dic2['newkey']  # returns 0 even not explicitly set

3. Keys and values related by a function.

For building a dictionary where keys and values are linked via a function, use a dictionary comprehension, as described in detail by @OmerB, e.g.

{k: f(k) for k in lst}  # value function of given keys
{f(v): v for v in lst}  # key function of given values
like image 80
jpp Avatar answered Dec 20 '22 13:12

jpp


Well, dictionary comprehension is one-line, is that what you mean?

>> MyList = ['apple', 'banana', 'pear']
>> {hash(element): element for element in MyList}

{-8723846192743330971: 'pear',
 -6060554681585566095: 'banana',
 -4133088065282473265: 'apple'}

Also - I'm suspecting that using the element's hash as the key is not what you're looking for:

  • If your elements are immutable (e.g. strings), you could use the elements themselves as keys.
  • If they're not immutable, you can use the element's location in the list.

For the latter, to make sure you insert each value only once to the dict, clear duplicates from the list before iterating over it:

>> MyList = ['apple', 'apple', 'banana', 'banana', 'pear']
>> {idx: value for (idx,value) in enumerate(set(MyList))}
{0: 'banana', 1: 'pear', 2: 'apple'}
like image 35
OmerB Avatar answered Dec 20 '22 13:12

OmerB