2015-03-15 2 views
3

Моя программа получает источник данных со столбцами« значение »и« количество вхождений »в виде набора кортежей (value, frequency). В Python 2.6 или 2.7, я бы это сделать:Функция `key` для сортировки кортежей без магических чисел после PEP 3113

ls.sort(key=lambda (value, frequency): -frequency) 

Но Python 3 удален возможность распаковывать параметр кортежа. Это не так больно в названных функциях, потому что можно распаковать с помощью оператора присваивания в теле функции (Nested arguments in python not compiling). Но поскольку тело lambda не может использовать операторы присваивания, его невозможно распаковать (Python lambda does not accept tuple argument).

PEP 3113 рекомендует этот обходной путь:

ls.sort(key=lambda row: -row[1]) 

Но это использование 1 как magic number оставляет неприятный привкус во рту. Является ли использование таких магических чисел идиоматическими в Python 3? Или я должен создать именованную функцию для каждого случая, когда ранее я использовал распаковку кортежа в лямбда, например?

def negative_of_frequency_from_value_frequency_tuple(value_freq): 
    value, freq = value_freq 
    return -freq 

ls.sort(key=negative_of_frequency_from_value_frequency_tuple) 

Или я ошибка автор библиотеки, которая предоставляет эти кортежи вернуть named tuples вместо простых кортежей?

+0

Чтобы избежать магического числа, вы могли бы сделать, например, 'VALUE_INDEX, FREQ_INDEX = диапазон (2)'. – jonrsharpe

+0

Использование магических чисел в качестве индексов в порядке; если вы действительно не хотите, чтобы индекс, который мог быть произвольно посередине, использовал '-row [-1]', который бы полностью указывал на последний индекс. –

+0

Мне (и программам проверки кода), неиспользуемые локальные имена - это запах кода. Я использовал бы то, что вы называете обходным путем, lambda r: -r [1] ', даже в 2.x. –

ответ

0

Если вам нужна только деструкция одного уровня, вы можете получить тот же эффект с помощью обертки.

ls.sort(key=lambda x: (lambda value, frequency: frequency)(*x)) 

Если вам нужно несколько уровней, а затем использовать постижения

ls.sort(key=lambda x: next(-frequency for value, frequency in [x])) 
Смежные вопросы