-1

I have a list of numbers:

a = [4,4,4,4,4,4,4,4,4,........................,4,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4]

I want to transform the values according to a custom dictionary, for example:

cust_dict ={4:'four',1:'one',2:'two',3:'three'}

To get the following:

a= [four,four,four,four,four.....,four, three,two,....]

The only code I have done is with a for loop:

for i in range(len(a)):
   a[i] = cust_dict[a[i]]

Is there a more efficient way (in pure python), thus avoiding for-loop ? For a list of 35k items I took around 4ms with this code.

a_jelly_fish
  • 478
  • 6
  • 21
Pdeuxa
  • 651
  • 7
  • 27

4 Answers4

3

Thank for the mapping, I was looking exactly for something like that. In term of speed (on my list (35k entries)):

  1. List Comprehension (@Arvin Kushwaha): a = [cust_dict[i] for i in a] --> 3 ms
  2. Lambda Mapping(@Arvin Kushwaha) : a = list(map(lambda x: cust_dict[x], a)) --> 5.54ms
  3. Dict get Mapping(@Olvin Roght) : a=list(map(cust_dict.get, a) --> 2ms

PS: pandas mapping took 9ms (with transforming back the pd.series to a list) Thank you all!

Pdeuxa
  • 651
  • 7
  • 27
  • Depending on further needs, you may want to keep things as an array or series, instead of using lists again. Lists can be fast, but at some point, an array or series will outdo a Python list. – 9769953 Jul 30 '20 at 10:27
  • I agree, if I have additionnal processing behind, to let things in series or arrays. – Pdeuxa Jul 30 '20 at 10:29
  • 1
    @Pdeuxa, if you're really obsessed with execution time, you can replace you `cust_dict` with `cust_list = [None, 'one', 'two', 'three', 'four']` and use `list(map(cust_list.__getitem__, a))`, it should be slightly faster. – Olvin Roght Jul 30 '20 at 10:36
1

Have a look at this:

a= [4,4,4,4,4,4,4,4,4,4,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4]

cust_dict ={4:'four',1:'one',2:'two',3:'three'}

output = list(map(lambda x: cust_dict[x], a))

print(output)
# ['four', 'four', 'four', 'four', 'four', 'four', 'four', 'four', 'four', 'four', 'three', 'two', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'four']
MisterNox
  • 1,445
  • 2
  • 8
  • 22
1

With 35K items, I would use a NumPy array, or in this context, a Pandas Series (this obviously ignores the "pure Python" mention in your question):

>>> import pandas as pd
>>> a = [4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 4, 4, 4, 1, 1, 1, 1, 2, 2, 2, 3]
>>> cust_dict ={4:'four',1:'one',2:'two',3:'three'}
>>> s = pd.Series(a)
>>> s.map(cust_dict).tolist()
['four', 'four', 'four', 'four', 'four', 'four', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'three', 'two', 'two', 'two', 'four', 'four', 'four', 'one', 'one', 'one', 'one', 'two', 'two', 'two', 'three']

But you may not want to convert the series back to a list, depending on further needs and usage.

9769953
  • 10,344
  • 3
  • 26
  • 37
0

a[:] = map(lambda x:cust_dict[x], a)

SID007
  • 21
  • 3