1

I have the following python code snippet involving dictionary,

    sample_dict = {
        "name": "Kelly",
        "age": 25,
        "salary": 8000,
        "city": "New york"
    }
    keys = ["name", "salary"]
    sample_dict = {k: sample_dict[k] for k in sample_dict.keys() - keys}
    print(sample_dict)

Why the output is {'city': 'New york', 'age': 25} and not {'age': 25, 'city': 'New york'}?

What causes the reverse ordering of dictionary keys? Any help will be highly appreciated. I executed the code on Spyder and Python 3.8.5 version.

AcK
  • 2,063
  • 2
  • 20
  • 27
Aleph
  • 224
  • 1
  • 11

2 Answers2

2

I guess the order is lost during processing of - between your keys() and your keys list (because it involves conversion to sets which are unordered). You can build your comprehension as follow to prevent it.

keys = {"name", "salary"}
sample_dict = {k: sample_dict[k] for k in sample_dict.keys() if k not in keys}
Tranbi
  • 11,407
  • 6
  • 16
  • 33
  • 1
    Yes removing the - sign indeed prevents changing the order. But i was actually looking for a justification for what is actually causing the order change. – Aleph Nov 16 '22 at 07:43
  • Seen your updated answer, thanks. – Aleph Nov 16 '22 at 07:43
  • Also why does the - sign between the keys converts the keys to set? – Aleph Nov 16 '22 at 08:45
  • 1
    `-` calls the [difference](https://python-reference.readthedocs.io/en/latest/docs/sets/difference.html) between two sets. The conversion to sets occurs implicitly as is often the case in Python. See also https://docs.python.org/3/tutorial/datastructures.html – Tranbi Nov 16 '22 at 08:58
1

@Tranbi has provided the solution to the OP. I just supplement some materials.

Although dict preserves insertion order since 3.7.

Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.

set does not.

Being an unordered collection, sets do not record element position or order of insertion.

If you check the result of sample_dict.keys() - keys, you will find it is a set.

remain_keys = sample_dict.keys() - keys
print(type(remain_keys))
# set
for k in remain_keys:
    print(k)
# city
# age

Because dict.keys() returns a set-like view.

Keys views are set-like since their entries are unique and hashable. ... For set-like views, all of the operations defined for the abstract base class collections.abc.Set are available (for example, ==, <, or ^).

ILS
  • 1,224
  • 1
  • 8
  • 14
  • But thats not even in alphabetical order. How the ordering is decided for remain_keys ? – Aleph Nov 16 '22 at 07:49
  • 1
    @aleph, I **guess** it's related to `hash` function, collision, etc. If you iterate over `s1 = set(["age", "city"])` and `s2 = set(["city", "age"])`, you will get the different results. I tried to find a reasonable explanation, but I failed. You can open a new question for that. [This](https://stackoverflow.com/questions/12165200/order-of-unordered-python-sets) may give you some insight. – ILS Nov 16 '22 at 08:24
  • @aleph, do not expect the order of a `set`, it's **arbitrary**. Therefore, it's meaningless to attention the order of a set. This [link](https://stackoverflow.com/a/15479974) reveals more details. – ILS Nov 16 '22 at 08:57