5

When I was reading this answer https://stackoverflow.com/a/9841401/5175044 to a question on removing duplicates from a string, I couldn't understand what the index attribute meant in

''.join(sorted(set(foo), key=foo.index)) 

I did this example run:

foo = "Wicked long string"
>>> "".join(sorted(set(foo),key = foo.index))
'Wicked longstr'
>>> "".join(sorted(set(foo)))
' Wcdegiklnorst'

which leads me to think that it helps in keeping the order of the characters.

Community
  • 1
  • 1
tulians
  • 439
  • 5
  • 23
  • Okay... so what is your question? – Cory Kramer Feb 21 '16 at 20:20
  • All sequences support the `.index` method, see https://docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange – jonrsharpe Feb 21 '16 at 20:20
  • This sorts a `set` (which is unordered) using the original lists index. So you get the same order as the original list. Without `key` it would just sort the characters lexically. – AChampion Feb 21 '16 at 20:21
  • @CoryKramer, I don't get what `.index` is, because it has nothing to do with `.index(sub[, start[, end]])`, does it? – tulians Feb 21 '16 at 20:22
  • @AChampion, so if I run `>>> for i in foo: print i.index` it returns every list element's original index? – tulians Feb 21 '16 at 20:28
  • you are sorting by the position of the character in the original string, on a sidenote it is a pretty inefficient way to do so for large strings. Using a dict to store the index and passing dict.get as the key would be better. – Padraic Cunningham Feb 21 '16 at 20:30
  • what you want to be reading is this: https://wiki.python.org/moin/HowTo/Sorting the part about Key Functions – Kuhlambo Feb 21 '16 at 20:33
  • so if you understand what the key parameter does you can look at what the .index does... – Kuhlambo Feb 21 '16 at 20:34
  • @tulians not quite the equivalent would be `>>> for i in foo: print foo.index(i)`. The `key` parameter is a function that is passed every element being sorted with the result being used to order the elements. – AChampion Feb 21 '16 at 20:41

2 Answers2

1

As mentioned by others Pythons sorted() function and the sort() method of a list provides the key parameter to specify a function to be called on each list element prior to making comparisons.

The key thing is that this key parameter is a function object that takes when it is called only one argument and returns exactly one value which is used for the sorting.

A anonymous "lambda" function is often used for this purpose, since its definition does not include a return statement and therefor always contains an one expression which is returned.

For instance

>>> myKey = lambda e: id(e)

creates an (anonymous) function object

>>> type(myKey)
<class 'function'>

which takes one argument and returns a value and would therefore be a valid key for sorting.

If you want to call the myKey function object now you would simply do this:

>>> myKey(42)
503732608

To solve your problem you could create a lambda function as key which takes an element and returns its index in the foo string to keep the order of the characters:

>>> foo = "Wicked long string"
>>> "".join(sorted(set(foo), key = lambda e: foo.index(e)))
'Wicked longstr'

On the other hand -- since foo.index is a function object itself which takes one argument and returns one value -- you could pass this object instead to the sorted() function and by-pass the lambda definition:

>>> "".join(sorted(set(foo),key = foo.index))
'Wicked longstr'

Hope this helps :)

Community
  • 1
  • 1
elegent
  • 3,857
  • 3
  • 23
  • 36
0

index is a method used for most ordered sequences to find the first occurrence of some element in that sequence. For example "My string is here.".index(" ") would return 2 because the first occurrence of " " is at position 2. It is used for strings, tuples, lists, etc. The documentation on sequences has more about it.

zondo
  • 19,901
  • 8
  • 44
  • 83
  • I understand the use of index when it has parameters. What I don't seem to understand is when it's used as an attribute. – tulians Feb 21 '16 at 20:26
  • Methods are not special attributes just because they are methods; they are attributes that can be moved around and referenced just like anything else. The `sorted` function has its own way of sorting, but you can also specify a key. This key is a function which, when given a value, returns a certain number that `sorted` will use to put that value in its list. In this case, The value of each element is its index in `foo`. That way all equal elements will have the same sort value, and will therefore be sorted next to each other. – zondo Feb 21 '16 at 20:31
  • @tulians the attribute is just a variable that stores a reference to that function that you can use like anything else. Try this: `x = 'hello'.index` then call like `x('o')`, `x('e')`, `x('y')`. – Two-Bit Alchemist Feb 25 '16 at 19:27