Why do dict1.items() <= dict2.items() and dict1.viewitems() <= dict2.viewitems() return different results?

dict.items() python 3
dictionary python
list comprehension || python
.values() python
python dictionary comprehension example
python dict_items
python dictionary methods
python dictionary items for loop

I am confused as to why .items() returns a different result than .viewitems() when comparing two dictionaries as a list.

# python 2.7
d1 = {'1': '10', '2': '20'}  # two key-value pairs
d2 = {'3': '30', '4': '40', '5': '50'}  # three key-value pairs
print d1 <= d2  # True
print d1.items() <= d2.items()  # True
print d1.viewitems() <= d2.viewitems()  # False
print d1.items()  # [('1', '10'), ('2', '20')]
print d1.viewitems()  # dict_items([('1', '10'), ('2', '20')])

Seems like the main difference between .items() and .viewitems() is that .items() returns a list and viewitems() returns a dict_items thingy.

Is it recommended to just use d1 <= d2 rather than viewitems or items when comparing the size between dictionaries?

Also, how to make this compatible with Python 3?

d1 <= d2  # True

It's complicated. And it's implementation detail. See What do comparison operators do on dictionaries? TL;DR: a shorter dictionary is always smaller than a longer one in Python 2.x, but dicts are not orderable at all in Python 3.x.

d1.items() <= d2.items()  # True

This is a lexicographical comparison of lists. That True result is reliable, since every key in d1 is less than any key of d2. To make this code cross-compatible, you would have to convert to list explicitly.

d1.viewitems() <= d2.viewitems()  # False

This is a subset-like check. That False result is reliable, because d1 is not a "subdict" of d2. To make this code cross-compatible, use six.viewitems or similar.

Is it recommended to just use d1 <= d2 rather than viewitems or items when comparing the size between dictionaries?

Neither, use len(d1) <= len(d2) to compare the size between dictionaries.

Python Dictionary items(), The syntax of items() method is: dictionary.items(). The items() method is similar to dictionary's viewitems() method in Python 2.7  dict1.items() dict_items([('c', 3), ('d', 4), ('a', 1), ('b', 2)]) This is the general template you can follow for dictionary comprehension in Python: dict_variable = {key:value for (key,value) in dictonary.items()} This can serve as the basic and the most simple template. This can get more and more complex as you add conditionalities to it.

I've answered a similar question here: Inconsistent behaviour between dict.values() and dict.keys() equality in Python 3.x and Python 2.7

The key thing to note is that dict.viewitems() is a Set-like object. Which means that when you do d1.viewitems() <= d2.viewitems() you are comparing checking if d1.viewitems() is a subset of d2.viewitems(), not the length comparison you expected. See the documentation here: https://docs.python.org/2.7/library/sets.html#set-objects

Operation         Equivalent  Result
s.issubset(t)     s <= t      test whether every element in s is in t
s.issuperset(t)   s >= t      test whether every element in t is in s

Note: because dict.viewitem() is a collections.Set object, it doesn't have .issubset or .issuperset methods like set does.

Observe the following:

>>> d1 = {'a': 0}
>>> d2 = {'a': 1}
>>> d3 = {'a': 0, 'b': 1}
>>> d1.viewitems() <= d3.viewitems()
True     # because [('a', 0)] is a subset of [('a', 0), ('b', 1)]
>>> d2.viewitems() <= d3.viewitems()
False    # because [('a', 1)] is not a subset of [('a', 0), ('b', 1)]

To answer your question though - as others have mentioned, to compare size, use len(d1) <= len(d2) instead.

Python for Developers: Learn to Develop Efficient Programs using , The question is when to use list(dict1.items()) and dict1.items(). Let us run a program: dict1 = {22: 'SSH', 23: 'Telnet', 53: 'DNS', 80: 'HTTP', 443: 'HTTPS'} for k,v​  In this article we will discuss how to add or append new key value pairs in a dictionary and also how to update value of existing keys. Python dictionary provides a member function update() i.e.

Your stated purpose is to compare dictionary sizes ... which you haven't done at all. You need to use len for that.

What you did do is comparing items of two very different types. items returns a list of tuples, which are easily compared by the well-known algorithms: check elements in the given order for relative value. Tuple comparison is familiar to most of us.

However, a dict_view is a dynamic view object, not a simple list of values. You're comparing a more complex object, not merely running down an obvious list of values. The ordering and comparison definition are not readily visible to us mere mortals.

Python Dictionary Comprehension Tutorial, dict1.items() dict_items([('c', 3), ('d', 4), ('a', 1), ('b', 2)]). This is the general template you can follow for dictionary comprehension in Python: What if we want to merged the contents of 2 or dictionaries to a new dictionary ? Let’s see how to do that. Merge two or more Dictionaries using **kwargs **kwargs. Using **kwargs we can send variable length key-value pairs to a function. When we apply ** to a dictionary, then it expands the contents in dictionary as a collection of key value

Learn Python in 7 Days, update() The syntax is given as: dict.update(dict2) dict2--this is the dictionary to by the keys of the dict1 dictionary. items() The syntax of the items() method is  Why Do Younger Black Voters Like Trump More Than Elders? Carrie Sheffield, Just the News June 11, 2020. AP Photo/Carolyn Kaster 'Because they're tired of hearing the same stories about victimhood

Python Interview Questions: Ultimate Guide to Success, Answer: The items() function does not take any parameters. It returns a view object that shows the given dictionary's key value pairs. >>> dict1 = {'English  Why are holds necessary? Holds protect your items. Steam accounts are valuable, especially if they have items, and that makes them appealing to thieves. Anyone participating in trading or the Community Market should have the highest level of security on their account.

Designing Microservices Using Django: Structuring, Deploying and , "Rohan"} # It is coping the dict1 object to dict2. dict2 = dict1.copy() # In the result dict2 of function name: items(): It is used for fetching both key and value. Most verses go on to list reasons why we should thank Him, such as “His love endures forever” (Psalm 136:3), “He is good” (Psalm 118:29), and “His mercy is everlasting” (Psalm 100:5). Thanksgiving and praise always go together.

  • If you want to compare sizes of dictionaries, do so explicitly: len(d1) < len(d2).
  • boo, python 2.x!
  • Python 2.7 did not define what, exactly, d1 <= d2 would mean. From docs.python.org/2.7/reference/expressions.html#comparisons: "Mappings (instances of dict) compare equal if and only if they have equal (key, value) pairs. Equality comparison of the keys and values enforces reflexivity. Outcomes other than equality are resolved consistently, but are not otherwise defined."
  • Unless you are maintaining legacy Python 2 code, you shouldn't be worried about the semantics; d1 <= d2 is a type error in Python 3, forcing you to use len(d1) <= len(d2).
  • @chepner yes, looking for python 3 compatibility
  • Wait, so both the True and False results are reliable? We are migrating from python 2 to 3, and a linter replaced viewitems() with items() and then caused a unit test to fail. If .items() and .viewitems() do something different than simply comparing sizes of dictionaries, then what should I do?
  • It depends, do you need cross-compatible code or just Python 3 compatible code? Did the unit test fail on Py 2 or Py 3?
  • Cross compatible code. Unit test failed on python 2, but the logic was kinda vague whether they are comparing keys, subset, or length of the dictionaries.
  • Your linter did the right thing (replacing viewitems with items) to convert py2 -> py3 code. But this is not a cross-compat code. For that you'll need to use six.viewitems or similar, as the answer mentioned.
  • The ordering and comparison definition is visible; the definition of the dict view objects specify that they implement the collections.abc.Set ABC, and while the ABC itself doesn't actually say what __le__/<= should do, any reasonable implementer would follow the rules set follows, namely, returning True if the the left hand side is a subset of, or equal to, the right hand side.