Python 2 and 3 compatible way to iterate through a dict with key and value

I have the following list comprehension that only works in Python 2 due to using iteritems() :

 foo = [key for key, value in some_dict.iteritems() if value['marked']] 

I can not import libraries. Is there a clean way to make this compatible in both Python 2 and 3?

+6
source share
4 answers

You can just use dict.items() in both Python 2 and 3,

 foo = [key for key, value in some_dict.items() if value['marked']] 

Or you can just collapse your own version of the items generator, like this

 def get_items(dict_object): for key in dict_object: yield key, dict_object[key] 

And then use it like this:

 for key, value in get_items({1: 2, 3: 4}): print key, value 
+7
source

I would say it is better to use the future module than to implement your own, many things are already done for you in a minimalistic / optimized way:

 from future.utils import viewitems foo = [key for key, value in viewitems(some_dict) if value.get('marked')] 

if you are wondering how this viewitems() works, it's that simple:

 def viewitems(obj, **kwargs): """ Function for iterating over dictionary items with the same set-like behaviour on Py2.7 as on Py3. Passes kwargs to method.""" func = getattr(obj, "viewitems", None) if not func: func = obj.items return func(**kwargs) 

Note: if compatibility with Python versions prior to 2.7 is necessary to use iteritems() :

 from future.utils import iteritems foo = [key for key, value in iteritems(some_dict) if value.get('marked')] 
+7
source

The easiest way is to not worry about creating a list simply by using dict.items() :

 foo = [key for key, value in some_dict.items() if value['marked']] 

The next option is to use an exception handler:

 try: # Python 2 iter_some_dict = some_dict.iteritems except AttributeError: # Python 3 iter_some_dict = some_dict.items foo = [key for key, value in iter_some_dict if value['marked']] 

What you use depends on how big some_dict , and if creating a list for all elements will have a significant impact on the performance and use of your memory. To determine this, you will need to compare your specific use case.

+5
source

Define your own iteritems :

 iteritems = lambda d: (getattr(d, 'iteritems') or d.items)() foo = [key for key, value in iteritems(some_dict) if value['marked']] 
+2
source

Source: https://habr.com/ru/post/979973/


All Articles