Если условие работает по-разному для того же значения в Python - PullRequest
2 голосов
/ 19 октября 2019

Я пытаюсь написать функцию, которая будет возвращать True или False, если заданное число не больше 2. Так просто, но условие if возвращает разные выходы для одного и того же значения '2'. Код, который я использовал: Код, который я использовал:

ele_list = [1,2,3,2]
for i in ele_list:
    if not i>2:
        print(i,False)
        ele_list.remove(i)
        print(ele_list)

Выходные данные, которые я получаю:

1 False
[2, 3, 2]
2 False
[3, 2]

Я смущен, увидев, что первые 2 в спискепроходя через условие if, но вторые 2 в списке не проходят через условие. Пожалуйста, помогите мне разобраться в этом ..

Ответы [ 3 ]

2 голосов
/ 19 октября 2019

проблема в том, что вы изменяете свой список во время итерации по нему, как упомянуто в ответе @ Olian04.

это звучит так, как будто вы действительно хотите сделать, но только сохранить значениякоторые > 2. это действительно легко, используя понимание списка:

filtereds_vals = [v for v in ele_list if v > 2]

, если вам просто нужна функция, которая дает вам True для чисел больше 2 и False для других, вы можете сделать что-то вроде этого:

def gt_2(lst):
    return [v > 2 for v in lst]

или, наконец, если вы хотите выяснить, является ли любое из значений > 2, просто сделайте:

def any_gt_2(lst):
    return any(v > 2 for v in lst)
1 голос
/ 19 октября 2019

Удаление элементов из списка, над которым вы зацикливаетесь, обычно плохая идея. Здесь происходит следующее: когда вы удаляете элемент, вы изменяете длину массива и, следовательно, изменяете, какие элементы расположены по каким индексам, а также меняете «цель» forloop.

Давайте посмотрим на следующий пример:

ele_list = [4,3,2,1]

for elem in ele_list:
  print(elem)
  ele_list.remove(elem)
  1. В первой итерации цикла elem это значение 4, которое находится в индексе 0. Затем вы удаляетеиз массива первое значение, равное elem. Другими словами, значение 4 в индексе 0 теперь удалено. Это сдвигает, какой элемент хранится в каком индексе. До удаления ele_list[0] будет равно 4, однако после удаления ele_list[0] будет равно 3, поскольку 3 - это значение, которое до удаления хранилось с индексом 1.
  2. Теперь, когдацикл продолжается до второй итерации, индекс, на который «смотрит» цикл, увеличивается на 1. Таким образом, переменная elem теперь будет иметь значение ele_list[1], которое в обновленном списке (после удаления значения 4 впредыдущая итерация) равна 2. Тогда вы (как и прежде) удаляете значение по индексу 1 из списка, так что теперь длина списка всего 2 элемента.
  3. Когда цикл собираетсязапустите третью итерацию, которую он проверяет, чтобы увидеть, меньше ли новый индекс (в данном случае 2), чем длина списка. Которого нет, так как 2 не меньше 2. Таким образом, цикл заканчивается.

Самое простое решение - создать новую копию массива и зациклить ее. Это легко сделать, используя синтаксис slice : ele_list[:]

ele_list = [1,2,3,2]

for elem in ele_list[:]:
  if not elem > 2:
    print(elem, False)
    ele_list.remove(elem)
    print(ele_list)
0 голосов
/ 19 октября 2019

Я думаю, что проблема здесь в том, как функция удаления взаимодействует с функцией for.

См. Документацию, прочитайте часть «примечания»: https://docs.python.org/3.7/reference/compound_stmts.html?highlight=while#grammar-token-for-stmt

Это может привести к неприятным ошибкам, которых можно избежать, сделав временную копию с использованием фрагмента всей последовательности

Возможное решение, предложенное в документации:

ele_list = [1,2,3,2]
for i in ele_list[:]:
    if not i>2:
        print(i,False)
        ele_list.remove(i)
        print(ele_list)
"""
1 False
[2, 3, 2]
2 False
[3, 2]
2 False
[3]
"""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...