Фильтрация списка двухэлементных подсписков с пониманием списка

1

У меня есть список списков

input = [[2,13],[5,3],[10,8],[13,4],[15,0],[17,10],[20,5],[25,9],[28,7],[31,0]]

Я хочу написать список, где для пар [a,b] выше я получаю пары, где b > a. В приведенном выше примере это будет [2,13].

Моя попытка

x = [[item[i],[j]] for item in inputArray if j>i]

создает NameError

NameError: name 'j' is not defined'
Теги:

2 ответа

1
Лучший ответ

Проблема с вашей попыткой заключается в том, что вы никогда не говорите Python, что должны быть i и j. Проверка j > i не может быть вычислена, и список [item[i],[j]] не может быть создан без этой информации.

Вы можете выдать

>>> inp = [[2,13],[5,3],[10,8],[13,4],[15,0],[17,10],[20,5],[25,9],[28,7],[31,0]]
>>> [[a, b] for a, b in inp if b > a]
[[2, 13]]

Это решение не генерирует NameError потому что for a, b in inp сообщает Python для итерации по элементам inp (двухэлементных подписок) и в каждой итерации присваивает имя a первому элементу подсписчика, а имя b - второй элемент.

Я использовал имя inp вместо input потому что последнее уже принято встроенной функцией для ввода пользователя.

Объяснение понимания списка

Понимание эквивалентно

>>> result = []
>>> for a, b in inp:
...     if b > a:
...         result.append([a, b])
... 
>>> result
[[2, 13]]

Каждый список из двух элементов в inp распаковывается в переменные a и b. Если условие фильтра b > a равно True, тогда список [a, b] строится и включается в окончательный результат.

Если вы не хотите использовать распаковку, вы можете также индекс в подсписки в inp, как это:

>>> [sub[:] for sub in inp if sub[1] > sub[0]]
[[2, 13]]

Принимая полный срез sub через sub[:] гарантирует, что, как и в других решениях представлены до сих пор, отфильтрованные результирующих магазинов (мелкий) копия подсписков в inp. Если копирование не требуется, вы можете опустить [:].

Этот код не генерирует NameError потому что for sub in inp указывает Python на итерацию по inp и в каждой итерации присваивает имя sub следующему подсписку. Кроме того, для индексов используются явные числа (0 и 1).

Лично я предпочитаю решение с распаковкой. Его легче читать и работать, даже если элементы inp не поддерживают индексирование, но являются итерабельными, из которых можно извлечь два элемента.

  • 1
    Спасибо! для объяснения и редактирования моего поста. Я буду задавать такие вопросы в следующий раз.
1

Вы должны распаковать каждую пару в переменные i, j, а затем вы можете сравнить их:

x = [[i, j] for i,j in inputList if j > i]

(обратите внимание, что я переименовал inputArray, inputList)


Или без распаковки:

x = [item for item in inputList if item[1] > item[0]]
  • 0
    Спасибо, это работает!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню