Программа python не проверяет символ «o» в строке

Я создал программу, в которой у меня есть список элементов: string, int и float. Я хотел удалить из списка элементы, которые не являются плавающими, или строки, в которых есть гласные.


mylist=['hey',20.0,'hey','hop',77,'orange',11,'yay',19,'hello','xyz','mop',11,30.5,90,'hat','on']
index=0
while (index<len(mylist)):
    var=mylist[index]
    if type(var) is int:
        mylist.pop(index)
    if type(var) is str:
        i=0
        while (i<len(var)):
            char=var[i]
            if (char=='a' or char=='e' or char=='i' or char=='u' or char=='o'):
                mylist.pop(index)
            i=i+1
    index=index+1
print(mylist)

Все работает нормально - значения с плавающей запятой остаются нетронутыми, а значения int выталкиваются, но 1. каким-то образом элементы в определенных местах не выталкиваются из списка, даже если они являются целыми. 2. все строки проверяются нормально, но строки, содержащие только «o», каким-то образом обходят оператор pop. Где я ошибаюсь?

Вы увеличиваете index = index + 1 каждый раз во внешнем цикле, но это приводит к тому, что вы пропускаете элементы. Допустим, вы начинаете с int 10 с индексом 0 и int 42 с индексом 1. На первой итерации ваш код выталкивается 10 из списка, поэтому 42 перемещается к индексу 0. Но на следующей итерации index равно 1, и так далее. 42 никогда не обрабатывается. См.: stackoverflow.com/questions/1207406/…

slothrop 17.08.2023 16:11

Кроме того, петля while выглядит неправильно — i=i+1 должна быть внутри петли.

slothrop 17.08.2023 16:11

Большое спасибо @slothrop! Цикл while был в порядке, просто опечатка, которую я сделал в посте. Детализация индекса действительно помогла мне: D

Suhani Gurjar 17.08.2023 16:18
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Основная проблема в вашем текущем коде заключается в том, что вы изменяете список, проходя по нему в цикле! В приведенном ниже коде я изменил его так, что у меня есть отдельный список, который будет результатом этого кода.

mylist=['hey', 20.0, 'hey', 'hop', 77, 'orange', 11, 'yay', 19, 'hello', 'xyz', 'mop', 11, 30.5, 90, 'hat', 'on']
newList = []

for var in mylist:
    if type(var) is int:
        continue
    elif type(var) is str:
        hasVowel = False
        for char in var:
            if (char in 'aeiou'):
                hasVowel = True
                break
        if not hasVowel:
            newList.append(var)
    else:
        newList.append(var)
print(newList)

Я заменил циклы while на циклы for, чтобы сделать код немного проще, поэтому я объясню код, если он кому-то понадобится.

Во-первых, я сохраняю ваш список, а затем создаю пустой список newList, который будет выводом. Затем я использую цикл for-each для перебора всех элементов в mylist. Если текущий элемент var имеет тип int, то я просто перехожу к следующему элементу, если он имеет тип str, я перебираю все символы в var и проверяю, являются ли какие-либо из них a, e, i, o или u. Если они есть, я использую переменную hasVowel, чтобы отметить, что в текущем var есть гласные. После этого я проверяю эту переменную и, если это False, я добавляю текущую var к newList. Наконец, если var любого другого типа (не int или str), я просто добавляю его к newList.

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

mylist = list(newList)

Причина, по которой я использую list() вместо того, чтобы просто установить его равным newList, заключается в том, что в случае, если какие-либо изменения будут внесены в newList позже в коде, это не повлияет на mylist.

Надеюсь это поможет :)

Спасибо! Хотя я не хотел создавать новый список, а хотел внести изменения только в тот же список. Ваше решение помогло мне исправить мое!

Suhani Gurjar 17.08.2023 17:34

Я добавил дополнительную строку кода, чтобы при необходимости изменить исходный список!

Borisonekenobi 17.08.2023 17:41
Ответ принят как подходящий

Он игнорирует что-либо в индексе сразу после того, что вы удалили, потому что вы увеличиваете index, даже когда вы выталкиваете что-то из списка (фактически пропуская следующее в индексе). Проблема только в игнорировании строк, содержащих букву o, потому что по совпадению эти строки находятся в этих слепых зонах в вашем списке.

Рассмотрим следующий код, предназначенный для удаления четных чисел из списка:

Ваш подход (всегда увеличивающийся индекс)

a = [0,0,1,1,2,2,3,3,4,4]

i = 0
while(i < len(a)):
  v = a[i]
  if ( v % 2 == 0):
    a.pop(i) # yeet if even
  # always increment i
  i += 1 

print("outcome from always incrementing i")
print(*a) # 0 1 1 2 3 3 4 (incorrect)

Правильный подход

b = [0,0,1,1,2,2,3,3,4,4]

i = 0
while (i < len(b)):
  v = b[i]
  if (v % 2 == 0):
    b.pop(i) # yeet current if even
  else:
    # only increment 'i' if we are not yeeting it
    i += 1

print ("outcome from only incrementing i if not popping")
print(*b) # 1 1 3 3 (correct)

Итак, если вы настроите свой код только на увеличение index, не удаляя элементы из списка, ваш код должен начать работать, как задумано.

Большое спасибо! Работал на меня

Suhani Gurjar 17.08.2023 17:48

Это крайне неэффективно. Просто используйте понимание списка и назначьте его исходной переменной списка. b = [n вместо n в b, если n % 2] Также... "пока"?

DarkKnight 17.08.2023 18:11

@DarkKnight Намерение состояло в том, чтобы помочь OP понять, почему их код не работает, заменив их код на MRE. Конечно, это может быть «ужасно неэффективный» способ удаления четных чисел из списка, но «просто показать OP понимание списка этого упрощенного MRE» не помогло бы.

11belowstudio 17.08.2023 18:47

Никогда не изменяйте список, который вы повторяете. В зависимости от того, что именно вы делаете, это может работать или не работать.

В этом случае нет необходимости изменять исходный список. Просто напишите функцию, которая определяет, является ли элемент в списке обязательным (или нет). Затем используйте понимание списка, чтобы создать новый список. Дискретная функция делает понимание списка менее громоздким.

Что-то вроде этого:

VOWELS = set('aeiouAEIOU')

def keep(v):
    match v:
        case float():
            return True
        case str():
            return not any(c in VOWELS for c in v)
        case _:
            return False

mylist = ['hey', 20.0, 'hey', 'hop', 77, 'orange', 11, 'yay', 19, 'hello', 'xyz', 'mop', 11, 30.5, 90, 'hat', 'on']

newlist = [e for e in mylist if keep(e)]

print(newlist)

Выход:

[20.0, 'xyz', 30.5]

Спасибо! Хотя я не хотел создавать новый список, а хотел внести изменения только в тот же список. Ваше решение помогло мне исправить мое!

Suhani Gurjar 17.08.2023 17:36

@SuhaniGurjar Итак, вместо создания нового списка просто назначьте понимание списка mylist. Это будет значительно эффективнее, чем изменение списка на месте.

DarkKnight 17.08.2023 18:06

Или сделайте mylist[:] = newlist, чтобы изменить объект, на который ссылается mylist (вместо переназначения), чтобы любая другая часть программы со ссылкой на mylist увидела изменение.

slothrop 17.08.2023 18:46

Другие вопросы по теме