213

When initializing a dictionary with d = {} Pycharm's code inspector generates a warning, saying

This dictionary creation could be rewritten as a dictionary literal.

If I rewrite it d = dict() the warning goes away. Since {} already is a dictionary literal, I'm pretty sure the message is erroneous. Furthermore, it seems like both d = {} and d = dict() are valid and Pythonic.

This related question seems to conclude that the choice is just a matter of style/preference: differences between "d = dict()" and "d = {}"

Why would Pycharm complain about d = {}?

UPDATE:

Mac nailed it. The warning actually applied to multiple lines, not just the one that was flagged.

Pycharm seems to look for a sequence of consecutive statements where you initialize a dictionary and then set values in the dictionary. For example, this will trigger the warning:

d = {}
d['a'] = 1

But this code will not:

d = {}
pass
d['a'] = 1
Community
  • 1
  • 1
Chris Sears
  • 6,502
  • 5
  • 32
  • 35
  • 3
    too noisy, and there is no real performance gain, just one more superfluous inspection – dashesy Jan 14 '15 at 18:10
  • Same thing happens for lists: a = [1]; a.append(2), probably because a=[1, 2] is nicer .... – cleros Sep 16 '15 at 21:02
  • yup. annoying message. all those underlines by PyCharm makes one uncomfortable before executing the program. – Rk.. Nov 11 '15 at 11:54
  • I found similar issue in JetBrains YouTrack - https://youtrack.jetbrains.com/issue/PY-19269#u=1461253420326 and it says: In this case PyCharm suggests that you can provide the value for the `something` attribute right into the dict literal instead of assigning it at the next line. – Dudnikof Dec 05 '16 at 08:17

5 Answers5

267

What is the code following your dictionary declaration?

I think PyCharm will trigger the error if you have something like:

dic = {}
dic['aaa'] = 5

as you could have written

dic = {'aaa': 5}

Note: The fact that the error goes away if you use the function dict(). This doesn't necessarily mean that pycharm believes dict() is a literal. It could just mean that it doesn't complain about it:

dic = dict()
dic['aaa'] = 5
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
mac
  • 42,153
  • 26
  • 121
  • 131
  • 7
    apparently it is for all these non-useful noisy inspections unfortunately some of my colleagues turn it off altogether, it is a shame because it is useful for many things like PEP, ..., real problems and real performance hints. – dashesy Jan 14 '15 at 18:09
  • In my case that type of rewriting is not possible, since each dictionary item that is created (but the first one) depends on the previous dictionary item created. So they have to be assigned to the dictionary one by one rather than every item at the same time. However, PyCharm still complains and says that I should create the dictionary as a dictionary literal. I guess I have to use the `dic = dict()` workaround... – HelloGoodbye Aug 10 '16 at 13:37
  • @HelloGoodbye - Without knowing the problem you are trying to solve I can't express a qualified opinion, but have you considered starting with `d = { 'aaa': f1(something) }` then `d = f2(d)` then `d = f3(d)` etc... Or alternatively `d['bbb'] = f2(d)`, `d['ccc'] = f3(d)` ...? – mac Aug 10 '16 at 21:15
  • The construction I have is `d = {}`, `d['a'] = A`, `d['b'] = f(d['a'])`, `d['c'] = f(d['b'])`, etc. – HelloGoodbye Aug 11 '16 at 07:47
  • 5
    @HelloGoodbye - So, why not to merge the first two with `d = {'a': A}` and then just keep the sequence as you outlined? – mac Aug 11 '16 at 14:14
  • @dashesy On the contrary, these inspections make the code more clear and readable for anyone who will have to maintain your code in the future. The real noise happens when you turn them off and start to write code based on "your own style". – Jeyekomon Nov 22 '21 at 15:44
23

This can be disabled in the Project Settings or Default Settings.

  • Navigate to Settings -> Inspections -> Python
  • Uncheck "Dictionary creation could be rewritten by dictionary literal"
Craig Jackson
  • 362
  • 2
  • 9
  • This is what I did and can confirm it works well. My code was: payload = {**BASEPAYLOAD, **ExtraPayload} to merge two dictionaries and it was throwing the error. – pa1983 Feb 05 '18 at 10:42
11

for those who like (just like me) to initialize dictionaries with single operation

d = {
  'a': 12,
  'b': 'foo',
  'c': 'bar'
}

instead of many lines like

d = dict()
d['a'] = 12
d['b'] = ....

in the end I ended up with this:

d = dict()
d.update({
  'a': 12,
  'b': 'foo',
  'c': 'bar'
})

Pycharm is not complaining on this

Igor.K
  • 244
  • 3
  • 10
  • 9
    I cringe. :( So, you actually increased the amount of code and made it less clear and running slower just to get rid of a warning in the editor you happen to use... I don't use pycharm, but I would assume there is some sort of configuration toggle that will disable the warning and allow you to keep on coding in a pythonic way. :) – mac Jan 06 '18 at 14:48
  • 3
    @mac I agree now. I was young and stupid ) since then I've changed (a bit) and just disabled those warnings – Igor.K Mar 11 '18 at 21:07
  • Lol! This must be the most memorable time-offset comment I ever received! ;) – mac Mar 11 '18 at 21:20
0
mydict = {
  a: 5,
  b:z+c/2
}

The dictionary could have been created directly without initialising them first and then reassigning new values.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
Asnim P Ansari
  • 1,932
  • 1
  • 18
  • 41
0

I have a situation where this warning is bugging the hell out of me. In my case, I'm populating my dict partially as literals and partially from a tuple output by a function, like so:

def get_other_values():
    return 3, 4

foo = {
    "a": 1,
    "b": 2
}
foo["c"], foo["d"] = get_other_values()

So, unless I create interim vars for the output of get_other_values, PEP8 generates this warning even though I'm creating the dict with literals. And I can't assign the c and d keys in the literal, since the values are output as a tuple.