Изменение нескольких элементов в списке с использованием понимания списка - PullRequest
2 голосов
/ 26 марта 2020

Пример:

example = [None, b'1', b'2', b'3', b'4', b'1', None, None, b'8', b'56', b'66', b'77', b'1', None]

Мне нужно изменить значения в этом списке следующим образом: bytes следует преобразовать в int, None в 0 и каждые 6-е и 7-й элемент к bool. Ожидаемый результат:

expected_output = [0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]

Моя попытка:

[int(value) if value else bool(value) if index in (5,6) else 0 for index, value in enumerate(example)]

Результат:

[0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, 0, 0]

Я знаю, что есть проблема в этой части моего кода:

[int(value) if value else bool(value) if index in (5,6) else 0 for index, value in enumerate(example)]
                                       ^
                                       |
                                       |

Как изменить каждый 6-й и 7-й элемент на bool?

Ответы [ 3 ]

2 голосов
/ 26 марта 2020

Вам необходимо проверить, равен ли индекс по модулю 7 (количеству элементов в каждой группе) 5 или 6. Но сначала вам нужно сделать это, поскольку b'1' также проходит тест if value:

[bool(value) if index % 7 in (5,6) else int(value) if value else 0 for index, value in enumerate(example)]

Выход:

[0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]
1 голос
/ 26 марта 2020

Basi c

Вы можете реализовать вращение с оператором % (по модулю).

example = [
    None, b'1', b'2', b'3', b'4', b'1', None,
    None, b'8', b'56', b'66', b'77', b'1', None,
]

results = [
    bool(value) if index % 7 in {5, 6} else
    int(value) if value else 0
    for index, value in enumerate(example)
]
print(results)

вывод:

[0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]

Pythoni c

Но есть еще несколько способов Pythoni c:

import itertools

example = [
    None, b'1', b'2', b'3', b'4', b'1', None,
    None, b'8', b'56', b'66', b'77', b'1', None,
]
converters = itertools.cycle(itertools.chain(
    itertools.repeat(lambda x: int(x) if x else 0, 5),
    itertools.repeat(bool, 2),
))

results = [
    converter(value) for converter, value in zip(converters, example)
]
print(results)

Вывод: то же, что и выше.

Объяснение

  • itertools.cycle: создание циклического итератора c.
  • itertools.chain: объединение итераций.
  • itertools.repeat: сделать итератор с повторением по указанному номеру.
  • Итак, converters = ... part означает: lambda x: int(x) if x else 0 функция с пятью разами, bool с двумя разами, и повторите этот цикл!
  • Вы можете добавить несколько правил для каждой позиции без сложных if - else.
1 голос
/ 26 марта 2020

Чем больше логик c вы добавите в этот список, тем более нечитаемым он станет. Я бы предложил вам go с нормальным if / elif оператором здесь:

for ix, i in enumerate(example):
    if ix % 7 in (5,6):
        example[ix] = bool(i)
    elif not i:
        example[ix] = 0
    elif isinstance(i, bytes):
        example[ix] = int(i)

print(example)
# [0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]
...