Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: 'cmp' is an invalid keyword argument for this function

I'm using Python3, but the script is not compatible with this version and I hit some errors. Now I have problem with cmp parameter. Here is the code

def my_cmp(x,y):
    counter = lambda x, items: reduce(lambda a,b:a+b, [list(x).count(xx) for xx in items])
    tmp =  cmp(counter(x, [2,3,4,5]), counter(y, [2,3,4,5]))
    return tmp if tmp!=0 else cmp(len(x),len(y)) 

for i, t in enumerate([tmp[0] for tmp in sorted(zip(tracks, self.mapping[idx][track_selection[-1]].iloc[0]), cmp=my_cmp, key=lambda x:x[1])]):
    img[i,:len(t)] = t

I would really appreciate any help how to deal with this error in Python3.

like image 717
ewilulu Avatar asked Feb 13 '15 15:02

ewilulu


2 Answers

from python documentation

In Python 2.7, the functools.cmp_to_key() function was added to the functools module.

The function available in python 3 too.

Just wrap your cmp function with cmp_to_key

from functools import cmp_to_key

...

...key=cmp_to_key(my_cmp)...
like image 119
user3506100 Avatar answered Sep 27 '22 18:09

user3506100


You should try to rewrite your cmp function to a key function instead. In this case it looks like you can simply return the counter() function output for just one element:

def my_key(elem):
    counter = lambda x, items: sum(list(x).count(xx) for xx in items)
    return counter(elem, [2, 3, 4, 5]), len(elem)

I took the liberty of replacing the reduce(...) code with the sum() function, a far more compact and readable method to sum a series of integers.

The above too will first sort by the output of counter(), and by the length of each sorted element in case of a tie.

The counter function is hugely inefficient however; I'd use a Counter() class here instead:

from collections import Counter

def my_key(elem):
    counter = lambda x, items: sum(Counter(i for i in x if i in items).values())
    return counter(elem, {2, 3, 4, 5}), len(elem)

This function will work in both Python 2 and 3:

sorted(zip(tracks, self.mapping[idx][track_selection[-1]].iloc[0]),
       key=lambda x: my_key(x[1]))

If you cannot, you can use the cmp_to_key() utility function to adapt your cmp argument, but take into account this is not an ideal solution (it affects performance).

like image 42
Martijn Pieters Avatar answered Sep 27 '22 20:09

Martijn Pieters