3

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.

5
  • You know that functions can return functions, right? Commented May 19, 2016 at 20:14
  • 1
    What is sortingAlgorithm() in your code ? The sorted() function has its own sorting algorithm, what it needs is instructions where each item should go, compared to the others. Key= needs to be "a function which takes a list item, and returns a number/string/sortable value". And as the answers come in, there are many approaches to that - but none of them involve passing a sorting algorithm to sort... Commented May 19, 2016 at 20:21
  • 1
    Are both values combined or is the second a tie-breaker? Commented May 19, 2016 at 20:31
  • @PadraicCunningham both values are combined Commented May 19, 2016 at 20:37
  • @Hossam, so dict1[x] + dict2[x] or dict2[dict1[x]]? Commented May 19, 2016 at 20:38

6 Answers 6

4

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]])
Sign up to request clarification or add additional context in comments.

8 Comments

Oooh, point -- I was thinking we needed a comparator, but that's not the case here.
Thanks for your answer, but can you please check my update?
@Hossam do you want a lexicographic sort on tuples in this case?
@YakymPirozhenko No, I want to use the values from both dictionaries and incorporate them in a function that returns the value that should be used for sorting.
@YakymPirozhenko Thank you.
|
1

Use a closure.

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

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

Comments

1

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']

Comments

1

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)

Comments

1

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.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.