Create a dictionary with additional values

I have a list and I want to generate a dictionary d by taking out duplicates and excluding one element, so that the first key has a value of 0, the second has a value of 1, etc.

I wrote the following code:

 d = {} i = 0 for l in a_list: if (l not in d) and (l != '<'): d[l] = i i += 1 

If a_list = ['a', 'b', '<', 'c', 'b', 'd'] , after running the code, d contains {'a': 0, 'b': 1, 'c': 2, 'd':3} . Order is not important. Is there a more elegant way to get the same result?

+5
source share
5 answers
 {b: a for a, b in enumerate(set(a_list) - {'<'})} 

set(a_list) creates a set of a_list . This effectively separates duplicate numbers in a_list since set can only contain unique values.

+3
source

Use dict.fromkeys to get unique occurrences (minus values ​​you don't need), then .update apply this sequence, for example:

 a_list = ['a', 'b', '<', 'c', 'b', 'd'] d = dict.fromkeys(el for el in a_list if el != '<') d.update((k, i) for i, k in enumerate(d)) 

Gives you:

 {'a': 0, 'b': 1, 'd': 2, 'c': 3} 

If order is important, use collections.OrderedDict.fromkeys to preserve the order of the original values ​​or sort unique values ​​if they should be in alphabetical order.

+5
source

Here you need to specify an ordered and manually filter the list:

 from collections import OrderedDict d = OrderedDict() new_list = [] a_list = [1,3,2,3,2,1,3,2,3,1] for i in a_list: if i not in new_list: new_list.append(i) for i, a in enumerate(new_list): if a != "<": d[i] = a 

Output:

 OrderedDict([(0, 1), (1, 3), (2, 2)]) 

If the original order is not important:

 final_d = {i:a for i, a in enumerate(set(a_list)) if a != "<"} 
+2
source

I personally find recursion a pretty elegant, tail recursion, especially like this:

 def f( d, a_list ): if a_list: if a_list[0] not in d and a_list[0] != '<': d[a_list[0]] = len(d) return f( d, a_list[1:] ) else: return d 

So,

 f( {}, "acbcbabcbabcb" ) 

will give

 {'a': 0, 'c': 1, 'b': 2} 

just as the original code does on the same input (modulo order of keys).

+2
source

If true:

Order is not important.

 {k: i for i, k in enumerate(filter(lambda x: x not in "<", set(a_list)))} # {'a': 3, 'b': 1, 'c': 0, 'd': 2} 

EDIT: @qnnnnez's answer uses a lot of operations, providing an elegant version of the latest code.

Otherwise, you can implement unique_everseen itertools recipe to maintain order. For convenience, you can import it from the library that implements this recipe for you, i.e. more_itertools .

 from more_itertools import unique_everseen {k: i for i, k in enumerate(filter(lambda x: x not in "<", unique_everseen(a_list)))} # {'a': 0, 'b': 1, 'c': 2, 'd': 3} 
+1
source

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


All Articles