2014-12-19 3 views
0

я словарь по имени «времена», которая отображает ключи строковые значения, которые представляют время:Как отсортировать словарь по значению, переданному через функцию?

times = {'key1': '12.23', 'key2': '43:53.29', 'key3': '1:38:11.50r'} 

Строка принимает форму [часы]: [мин.]: [Секунды] [миллисекунды] [ r] , где каждое поле является необязательным. R - это флаг, который не зависит от каких-либо других значений, заполняемых и не учитывающих сортировку. [часы] требует наличия [минут] и «вниз», но [минут] не требует [часов] для присутствия.

Я хочу привести список ключей, отсортированных по времени их значений.

У меня есть следующие:

standings = sorted(times, key=times.__getitem__) 

, но это только сорта на основе значения строки. Я новичок в python, но если бы я использовал java, я бы, вероятно, написал класс Time с пользовательской функцией compareTo(), чтобы заставить сортировку работать.

Я мог бы написать функцию, которая преобразует строку в определенное время в миллисекундах, а затем сортировать на ней, но не знаю, как это сделать, используя 'key =' в функции sorted().

+0

Что такое '' 50r' в '1: 38: 11.50r''? – thefourtheye

+0

полсекунды, в реле (это время гонки).«R» - это просто флаг, который не означает ничего для сортировки – PearSquirrel

ответ

2
import re 
def as_list(time): 
    """ 
    >>> as_list('1:38:11.50r') 
    [1, 38, 11, 50] 
    >>> as_list('2.23') 
    [0, 0, 2, 23] 
    """ 
    # Extract times and convert to integers 
    times = [int(x) for x in re.split(r"[:.]", re.sub("[a-z]$", "", time))] 
    # If needed pad from the left side with zeros and return 
    return times if len(times) == 4 else [0] * (4 - len(times)) + times 

[k for k, t in sorted(times.items(), key = lambda x: as_list(x[1]))] 

Или еще более краткий способ:

[key for _, key in sorted((as_list(v), k) for k, v in times.items())] 

Это работает, потому что списки или кортежи в Python сортируются в лексикографическом порядке. Допустим, у вас есть список следующим образом:

>>> l = [[0, 1], [-1 , 2, 3], [4, 5], [0, -1]] 

Вы можете назвать sorted на нем

>>> sorted(l) 
[[-1, 2, 3], [0, -1], [0, 1], [4, 5]] 

Следовательно, все волшебство.

Относительно [0] * (4 - len(times)) + times вы можете прочитать здесь: Create List of Single Item Repeated n Times in Python

Короче some_list * some_integer создает список, содержащий элементы some_list повторяется some_integer раз.

+0

Похоже, это работает! Я понимаю, что расщепление основано на ':' и '.', Игнорируя любые нечисловые символы. Не могли бы вы объяснить «время возврата, если len (times) == 4 else [0] * (4 - len (times)) + times» и «[k для k, t в отсортированных (times.items(), key = лямбда x: as_list (x [1]))] "? – PearSquirrel

+0

Я опубликовал обновление. Позвольте мне знать, объясняет ли это что-то. – zero323

+0

Вам не нужно '\ .',' .' не будет иметь специального значения с '[]'. Также используйте необработанные строки. – thefourtheye

0

Вы можете сделать следующее:

standings = sorted(times.items(),key = lambda t : t[0]) 

это предполагает, что вы хотите отсортировать по ключу словаря. Если вы хотите отсортировать по значению, замените t [0] на t [1].

Обратите внимание, что я использовал t [0], чтобы получить ссылку на ключ в качестве примера, но в вашем случае вы ссылаетесь на t [1], но вы, вероятно, передадите это значение функции, которая преобразует время в который будет легко сортировать лексикографически. Например, предположим, что у вас есть метод time_format, который возвращает заполненное время, тогда вы заменили t [0] выше на time_format (t [1]).

+0

, который дает мне отсортированный список значений. Мне нужен список ключей, отсортированных по функции их значений. – PearSquirrel

+0

Итак, {Bob: 2, Jim: 5, Billy: 3} даст что-то вроде [Bob, Billy, Jim] – PearSquirrel

0

Я думаю, вы можете определить функцию to_decimal, чтобы преобразовать строку времени в десятичное для сравнения, то:

standings = sorted(times, key = lambda x : to_decimal(times[x])) 
+0

как бы вы преобразовали в десятичную? Я не уверен, что 1.43.23.43 будет работать – PearSquirrel

+0

Думаю, вам нужно проанализировать строку, чтобы определить единицу каждой части, а затем суммировать до десятичной. – ciphor

+0

, значит, вы хотите преобразовать время в миллисекунды, а затем отсортировать? – PearSquirrel

 Смежные вопросы

  • Нет связанных вопросов^_^