Hossam
Hossam

Reputation: 41

Python: Arguments to sorting function

I am trying to sort a python list of strings. I know that I can use the method sorted and set the attribute key to be a function that implements the behavior I need to sort the elements of the dictionary on. My problem is that this method needs an argument.

UPDATE: I want the method to generalize to multiple arguments.

Example: I want to sort a list of strings based on their priorities in 2 dictionaries . So I need to use those priority dictionaries in sorting the list.

I want something like:

sorted(myList, key=sortingAlgorithm(priorityDictionary1, priorityDictionary2), reverse=True) 

This can be done if I set the priority dictionaries as global variables and then I will not need to have it as an argument to the sorting algorithm. But, I want to be able to do it without global variables.

If this is not possible, can you please recommend the pythonic way of doing this.

Thanks in advance.

Upvotes: 3

Views: 308

Answers (6)

hilberts_drinking_problem
hilberts_drinking_problem

Reputation: 11602

Try key=priorityDictionary.get

get is a method on a dictionary that takes a key and returns a value, if one is found.

Edit: The above solution applies to a case of a single dict. Here is a generalization where values of priorityDict2 are keys for priorityDict1.

And, as Padriac Cunningham points out, you can use a lambda to sort using nested dicts:

output = sorted(myList, key=lambda element: priorityDict1[priorityDict2[element]])

Upvotes: 4

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

If you want to pass the value from one dict as the key to the next you need a function or a lambda:

l = ["foo", "Foo", "Bar", "bar", "foobar", "Foobar"]

d1 = {"f": 1, "F": 0, "b": 1, "B": 0}
d2 = {1: 10, 0: 20}
print(sorted(l, key=lambda x: d2[d1[x[0]]]))

If a key may not exist you can still use get:

sorted(l, key=lambda x: d2.get(d1.get(x[0], {}), some_default))

Just make sure some_default makes sense and can be compared to the other values.

Upvotes: 1

solidpixel
solidpixel

Reputation: 12069

Some slightly more standalone examples:

stringList = ["A1", "B3", "C2", "D4"]
priorityDict = {"A1": 1, "B3": 3, "C2": 2, "D4": 4}

# Reference an accessor function
print sorted(stringList, key=priorityDict.get)

# Provide a lambda function (with "free" closure)
print sorted(stringList, key=lambda x: priorityDict[x])

# Provide a normal function (helper definition needs scope visibility 
# on priority dict, but doesn't have to be global - you can define 
# functions in the scope of other functions a little like lambdas)
def myKey(x):
    return priorityDict[x]

print sorted(stringList, key=myKey)

Upvotes: 1

Vedang Mehta
Vedang Mehta

Reputation: 2254

Code -

priorities = {'xyz' : 1, 'cde' : 3, 'abc' : 4, 'pqr' : 2}

arr = ['abc', 'cde', 'pqr', 'xyz', 'cde', 'abc']

arr.sort(key = lambda s : priorities[s])

print(arr)

Output -

['xyz', 'pqr', 'cde', 'cde', 'abc', 'abc']

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 295363

def sortingAlgorithm(primaryDictionary):
  def __cmp__(a, b):
    pass # do something with a, b, and primaryDictionary here
  return __cmp__

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798566

Use a closure.

def something(foo):
  def somethingsomething(bar):
    return foo(bar)
  return somethingsomething

baz = something(len)
print baz('quux')

Upvotes: 1

Related Questions