2
\$\begingroup\$

I need a constant (dictionary with values and default return value if there are no defined value for a key). Searching for any ways to simplify the code.

Without a default value I can simply define a dictionary like this:

REDUCE_VALUE = {
 "honda": 0.95,
 "suzuki": 0.85,
 "yamaha": 0.87
}

But with a default value it looks not so good:

from collections import defaultdict
REDUCE_VALUE = defaultdict(lambda: "0.9")
REDUCE_VALUE["honda"] = 0.95
REDUCE_VALUE["suzuki"] = 0.85
REDUCE_VALUE["yamaha"] = 0.87
asked Oct 24, 2016 at 9:14
\$\endgroup\$
4
  • \$\begingroup\$ Are you aware that there can't be two different "suzuki" entries in the dictionary? I'm not sure that this code does what you intend. \$\endgroup\$ Commented Oct 24, 2016 at 10:05
  • 1
    \$\begingroup\$ The get method of the standard dictionary returns a default value when the given key is missing. \$\endgroup\$ Commented Oct 24, 2016 at 10:10
  • \$\begingroup\$ Yes, there is an error with double "suzuki". The last one can be "bmw" for example. An second one default value must be in integer, not string. Thanks. I suppose it's a bad idea to edit my question after publication. \$\endgroup\$ Commented Oct 24, 2016 at 11:14
  • \$\begingroup\$ @misterioss Yes, it's a bad idea to remove or replace the part which has already been answered or commented. However, I suppose you can safely extend a question by adding a new part to it. Or, even better, make another, corrected question and add a follow-up note. \$\endgroup\$ Commented Oct 24, 2016 at 13:20

3 Answers 3

4
\$\begingroup\$

The same way that you would with dict. From the documentation for collections.defaultdict it says:

The first argument provides the initial value for the default_factory attribute; it defaults to None. All remaining arguments are treated the same as if they were passed to the dict constructor, including keyword arguments.

This means we can use all, bar b, of: (from the dict docs.)

>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True

Since you're overwriting suzuki, I'd remove the first assignment, as dicts are unordered, and so it's up to chance which it uses. And as Alex points out, you should keep the value data type consistent.

REDUCE_VALUE = defaultdict(lambda: 0.9, {"honda": 0.95, "suzuki": 0.87})
answered Oct 24, 2016 at 10:09
\$\endgroup\$
2
  • \$\begingroup\$ @Graipher Gotta love it when that happens, :) Feel free to answer anyway, quality over FGITW. \$\endgroup\$ Commented Oct 24, 2016 at 10:11
  • \$\begingroup\$ Nah, yours has nicer quotes from the docs. I wrote up what @mkrieger suggested, though. \$\endgroup\$ Commented Oct 24, 2016 at 10:17
3
\$\begingroup\$

You can use update method of dictionary to make it pretty

from collections import defaultdict
REDUCE_VALUE = defaultdict(lambda: "0.9")
REDUCE_VALUE.update({
"honda": 0.95,
"suzuki": 0.85,
"suzuki": 0.87
})

Also please note that in you defaultdict definition you are using string as value, while other values are floats, not sure which one you need. So fix it yourself.

Graipher
41.6k7 gold badges70 silver badges134 bronze badges
answered Oct 24, 2016 at 9:23
\$\endgroup\$
1
\$\begingroup\$

As @mkrieger1 commented, you could use dict.get.

From the python docs:

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

REDUCE_VALUE = {
 "honda": 0.95,
 "suzuki": 0.85,
}
>>> REDUCE_VALUE.get('suzuki', 0.95)
0.85
>> REDUCE_VALUE.get('yamaha', 0.95)
0.95

Normally, you would probably define the default value as a constant, instead of having it as a magic number as I did here.

answered Oct 24, 2016 at 10:17
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.