📜 ⬆️ ⬇️

Dictionary generators

Some of the great features of the Python language are undeservedly ignored and many programmers do not know about them. This time it will be a question of an excellent language opportunity that makes the code clearer: dictionary generators are single-line expressions that return a dictionary. But let's start with compact list generators and the task of removing non-unique elements of collections.

It will be interesting mainly to beginners in Python.

List generators


The easiest way to create a list is to use a single-line expression - a list generator. It is used quite often, and I have met it in many examples and in the code of many libraries.
Suppose that we have a function that returns a list. A good example is the range (start, end) function, which returns numbers between start and end . Starting with Python 3.0, it is implemented as a generator and does not immediately return a complete list, but returns number by number as needed. In Python 2. *, the xrange () function was used for this. Getting a list of numbers from 1 to 10 using this function could look like this:
numbers = [] for i in range(1, 11): numbers.append(i) 

If we need only even numbers, we could implement it as follows:
 numbers = [] for i in range(1, 11): if i % 2 == 0: numbers.append(i) 

List generators make code much easier. This is the expression that returns a list in general:
 [ expression for item in list if conditional ] 

Using it, the first example can be rewritten as:
 numbers = [i for i in range(1, 11)] 

and the second is:
 numbers = [i for i in range(1, 11) if i % 2 == 0] 

Of course, this syntax may seem strange at first glance, but when you get used to it, the code will become simpler and clearer.
')
Remove duplicates

Another common task when working with collections is the removal of identical elements. It can be solved by a variety of methods.
Suppose we work with this list:
 numbers = [i for i in range(1,11)] + [i for i in range(1,6)] 

The most difficult way to remove duplicates, which I met, looks like this:
 unique_numbers = [] for n in numbers: if n not in unique_numbers: unique_numbers.append(n) 

Of course, and it works, but there are easier solutions. You can use the standard type set. Sets can not contain the same elements by definition, so if you convert the list into a set - duplicates are deleted. But we will get a lot and not a list, so if we want a list of unique values, we need to convert again:
 unique_numbers = list(set(numbers)) 


Deleting duplicate objects

A completely different situation with objects or dictionaries. For example, we have a list of dictionaries in which one of the values ​​is used as an identifier:
 data = [ {'id': 10, 'data': '...'}, {'id': 11, 'data': '...'}, {'id': 12, 'data': '...'}, {'id': 10, 'data': '...'}, {'id': 11, 'data': '...'}, ] 

Deleting can be implemented with more or less code. Of course, the less - the better! The long version might look like this:
 unique_data = [] for d in data: data_exists = False for ud in unique_data: if ud['id'] == d['id']: data_exists = True break if not data_exists: unique_data.append(d) 


You can get the same result using the opportunity I found out a couple of days ago: dictionary generators. They have syntax similar to list generators, but return a dictionary:
 { key:value for item in list if conditional } 

If you rewrite the code from the example above with the use of this feature, there will be only one line:
 { d['id']:d for d in data }.values() 

In this line of code, a dictionary is created, the keys of which are the fields that we have taken as a unique identifier, then using the values ​​() method, we get all the values ​​from the created dictionary. Since the dictionary can contain no more than one entry for each key - the resulting list does not contain duplicates, which is what we needed.
This feature was added to Python 3.0 and backported to Python 2.7. In earlier versions, you can use a structure like this to solve this problem:
 dict((key, value) for item in list if condition) 

A list of tuples (pairs) is generated and passed to their dict () constructor, which takes the first element of the tuple as the key and the second as the value. With this approach, the solution of the same problem will look like this:
 dict((d['id'], d) for d in data).values() 

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


All Articles