У меня есть список списков
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'
Проблема с вашей попыткой заключается в том, что вы никогда не говорите 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
не поддерживают индексирование, но являются итерабельными, из которых можно извлечь два элемента.
Вы должны распаковать каждую пару в переменные 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]]