Python 程序不检查字符串中的“O”字符 [duplicate]

python program not checking for 'o' character in string [duplicate]

提问人:Suhani Gurjar 提问时间:8/17/2023 最后编辑:BorisonekenobiSuhani Gurjar 更新时间:8/18/2023 访问量:85

问:

我创建了一个程序,其中我有一个元素列表,分别是 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. 不知何故,某些地方的元素不会从列表中弹出,即使它们是 int 和
  2. 所有字符串都检查良好,但只有“o”的字符串以某种方式绕过了 pop 语句。
python 字符串 列表 浮点 整数

评论

2赞 slothrop 8/17/2023
你每次都会通过外循环递增,但这会导致你错过项目。假设您从索引 0 处的 int 和索引 1 处的 int 开始。在第一次迭代时,您的代码会从列表中弹出,因此会移动到索引 0。但在下一次迭代中,是 1,因此永远不会被处理。请参阅:stackoverflow.com/questions/1207406/...index = index + 110421042index42
0赞 slothrop 8/17/2023
此外,循环看起来不对 - 需要在循环内。whilei=i+1
1赞 Suhani Gurjar 8/17/2023
非常感谢@slothrop!while 循环没问题,只是我在帖子中犯了一个打字错误。尽管索引详细信息确实帮助了我:D

答:

1赞 Borisonekenobi 8/17/2023 #1

当前代码中的主要问题是,在循环访问列表时,您正在修改列表!在下面的代码中,我对其进行了更改,以便我有一个单独的列表,该列表将是此代码的结果。

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 循环,以使代码更简单一些,因此如果有人需要它,我将解释代码。

首先,我保留您的列表,然后创建一个空列表,该列表将成为输出。然后,我使用 for-each 循环遍历 中的所有元素。如果当前元素 , 是 类型,那么我继续下一个元素,如果它是类型,我会遍历 中的所有字符,并检查其中是否有任何字符是 、 、 、 或 。如果是,我使用变量来标记当前有元音。之后,我检查这个变量,如果是,我将电流添加到 .最后,如果是任何其他类型(不是或),我只需将其添加到 .newListmylistvarintstrvaraeiouhasVowelvarFalsevarnewListvarintstrnewList

如果要在代码末尾应用所有更改,可以添加以下代码行:mylist

mylist = list(newList)

我之所以使用,而不是仅仅将其设置为等于,是因为万一在代码后面进行了任何更改,它不会影响。list()newListnewListmylist

希望这对:)有所帮助

评论

0赞 Suhani Gurjar 8/17/2023
谢谢!虽然我不想创建一个新列表,而是只想对同一个列表进行更改。你的解决方案帮助我修复了我的!
0赞 Borisonekenobi 8/17/2023
如果需要,我添加了一行额外的代码来帮助更改原始列表!
-1赞 11belowstudio 8/17/2023 #2

在您删除某些内容后,它会立即忽略索引中的任何内容,因为即使您从列表中弹出某些内容,您也会递增(有效地跳过索引中的下一个内容)。该问题似乎只忽略了包含该字母的字符串,因为巧合的是,这些字符串恰好位于列表中的这些盲点中。indexo

请考虑以下代码,这些代码旨在从列表中删除偶数:

您的方法(始终递增索引)

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

i = 0
while(i < len(a)):
  v = a[i]
  if ( v % 2 == 0):
    a.pop(i) # pop the item at index i if it is even
  # always increment i
  i += 1 

print("outcome from always incrementing i")
print(*a) # 8 1 8 3 8 (incorrect - 'why is it not removing eights???')

“正确”的方法(仅在不弹出任何内容的迭代中递增 i)

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

i = 0
while (i < len(b)):
  v = b[i]
  if (v % 2 == 0):
    b.pop(i) # pop item at index 'i' if it's even
  else:
    # only increment 'i' if we did not pop it
    i += 1

print ("outcome from only incrementing i if not popping")
print(*b) # 1 3 (correct - all even numbers are removed, including eights)

乍一看,第一个示例似乎只是“不删除 s”(就像您的代码似乎“不删除包含字母的单词”) - 但是,从第二个示例中对增量所做的微小更改可以看出,问题是由于您的方法在列表中留下了盲点 - 盲点恰好在此示例中包含 s, 或代码中带有 an 的字符串。8oindex8o

因此,如果您要调整代码以仅在不从列表中删除内容时递增,则代码应按预期开始工作。index

评论

1赞 CtrlZ 8/18/2023
这是非常低效的。只需使用列表推导式并将其分配给原始列表变量即可。b = [n 表示 b 中的 n 如果 n % 2]也。。。“呀”?
0赞 11belowstudio 8/18/2023
@DarkKnight 其目的是通过用 MRE 替换代码来帮助 OP 准确理解为什么他们的代码不起作用。当然,这可能是从列表中删除偶数的一种“低效”的方法,但“仅仅向 OP 展示对这种过于简化的 MRE 的列表理解”无济于事。
1赞 Borisonekenobi 8/18/2023
也许 OP 目前没有寻找最有效的解决方案,但您的解决方案有点偏离了轨道,并且没有很好地解释问题所在。还有......“呀”?
0赞 11belowstudio 8/18/2023
@Borisonekenobi我试图稍微改写一下解释,希望现在更清楚一些
0赞 CtrlZ 8/17/2023 #3

切勿修改要迭代的列表。根据您正在执行的确切操作,它可能会起作用,也可能不会起作用。

在这种情况下,无需修改原始列表。只需编写一个函数来确定列表中的某个元素是否必需。然后使用列表推导来构建一个新列表。离散函数使列表理解不那么繁琐。

像这样的东西:

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]

评论

0赞 Suhani Gurjar 8/17/2023
谢谢!虽然我不想创建一个新列表,而是只想对同一个列表进行更改。你的解决方案帮助我修复了我的!
0赞 CtrlZ 8/18/2023
@SuhaniGurjar 因此,无需创建新列表,只需将列表推导式分配给 mylist。这将比就地修改列表更有效率
0赞 slothrop 8/18/2023
或者 do 来改变 所引用的对象(而不是重新赋值),以便程序的任何其他部分都能看到 所引用的更改。mylist[:] = newlistmylistmylist