2016-12-26 4 views
0

Я хотел бы заменить значение None значением 0 или 1 в зависимости от некоторых внешних условий. Мое решение:заменить None из списка с двумя значениями

my_list = [3, 4, 5, None, 6, 7, None, 8, None] 
my_list = [(1 if external_string == "ONE" else 0) if v is None else v for v in my_list] 

Является ли это питоническим способом решения проблемы? Давайте предположим иметь более двух возможных значений строки, чтобы присвоить, например, 0, если external_string - "ZERO", 1, если external_string, если "ONE", 2, если external_string - "TWO" и так далее: в этом случае способ, которым я пишу код выше стилистически приемлемо?

ответ

5

Если есть много вариантов external_string лучше использовать словарь, который сохраняет все возможности затем выберите собственно замена значения с помощью external_string:

all_options = {'ZERO':0, 'ONE':1, 'TWO':2, 'THREE': 3} 

my_list = [all_options[external_string] if v is None else v for v in my_list] 

Обратите внимание, что вместо того, чтобы с помощью прямого индексирования вы можете также использовать dict.get() метод, который будет возвращать None (по умолчанию), если ключ не существует в словаре или вы можете передать пользовательское значение, чтобы его можно было передать в случае отсутствия ключа.

5

Поскольку external_string не изменяется в цикле, так что вы можете рассчитать стоимость замены сразу:

replacement = 1 if external_string == 'ONE' else 0 
my_list = [replacement if v is None else v for v in my_list] 

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

def replace(value): 
    if value is not None: 
     return value 
    return 1 if external_string == 'ONE' else 0 

my_list = [replace(v) for v in my_list] 

Не пытайтесь втиснуть все в понимание списка; показатель удобочитаемости!

Для несколько вариантов, рассмотреть возможность использования словаря, отображающий внешнюю строку значений замены:

external_string_map = {'ONE': 1, 'TWO': 2} # etc. 
replacement = external_string_map.get(external_string, 0) 
my_list = [replacement if v is None else v for v in my_list] 
+1

Это неправильный способ, если OP имеет дело с более чем 2-3 вариантами, как указано в OP. – Kasramvd

+1

@ Kasramvd: В этот момент вы используете функцию. –