为了账号安全,请及时绑定邮箱和手机立即绑定

遍历列表并使用 remove() 不会产生预期的结果

遍历列表并使用 remove() 不会产生预期的结果

慕容3067478 2023-03-08 14:38:48
我是一名编程新手,希望获得一些帮助来理解为什么以下算法以特定方式运行。我的目标是让函数读取包含单词(可以大写)的文本文件,去除空格,将项目拆分为单独的行,将所有首字母大写的字符转换为小写,删除所有单个字符(例如,“a”, “b”、“c”等),并将生成的单词添加到列表中。所有单词都将成为列表中的单独项目以供进一步处理。输入文件:文本文件('sample.txt')包含以下数据 - “a apple b Banana c cherry”期望的输出:['apple', 'banana', 'cherry']在我最初的尝试中,我尝试遍历单词列表以测试它们的长度是否等于 1。如果是,则该单词将从列表中删除,而其他单词则保留在列表中。这导致了以下非预期的输出:[None, None, None]filename = ‘sample.txt’with open(filename) as input_file:    word_list = input_file.read().strip().split(' ')    word_list = [word.lower() for word in word_list]    word_list = [word_list.remove(word) for word in word_list if len(word) == 1]print(word_list)产生的非预期输出 = [None, None, None]我的下一个尝试是遍历单词列表以测试它们的长度是否大于 1。如果是,则将单词添加到列表中(留下单个字符)。使用此方法实现了所需的输出。filename = ‘sample.txt’with open(filename) as input_file:    word_list = input_file.read().strip().split(' ')    word_list = [word.lower() for word in word_list]    word_list = [word for word in word_list if len(word) > 1]print(word_list)产生所需的输出 = ['apple', 'banana', 'cherry']我的问题是:为什么最初的代码看起来最合乎逻辑、最有效,却没有产生预期的结果?达到预期结果的最佳“Pythonic”方式是什么?
查看完整描述

4 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

你得到你得到的输出的原因是

  1. 您在循环遍历列表时正在从列表中删除项目

  2. 您正在尝试使用list.remove(仅修改列表并返回None)的输出

您最后的列表理解 ( word_list = [word_list.remove(word) for word in word_list if len(word) == 1]) 本质上等同于:

new_word_list = []

for word in word_list:

    if len(word) == 1:

        new_word_list.append(word_list.remove(word))

word_list = new_word_list

当你遍历它时,会发生这种情况:


# word_list == ['a', 'apple', 'b', 'banana', 'c', 'cherry']

# new_word_list == []


word = word_list[0]  # word == 'a'


new_word_list.append(word_list.remove(word))


# word_list == ['apple', 'b', 'banana', 'c', 'cherry']

# new_word_list == [None]


word = word_list[1]  # word == 'b'


new_word_list.append(word_list.remove(word))


# word_list == ['apple', 'banana', 'c', 'cherry']

# new_word_list == [None, None]


word = word_list[2]  # word == 'c'


new_word_list.append(word_list.remove(word))


# word_list == ['apple', 'banana', 'cherry']

# new_word_list == [None, None, None]


word_list = new_word_list


# word_list == [None, None, None]

最好的“Pythonic”方式(在我看来)是:


with open('sample.txt') as input_file:

    file_content = input_file.read()


word_list = []

for word in file_content.strip().split(' '):

    if len(word) == 1:

        continue

    word_list.append(word.lower())


print(word_list)


查看完整回答
反对 回复 2023-03-08
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

在您的第一种方法中,您将结果存储word_list.remove(word)在无列表中。Bcz list.remove() 方法只返回对给定列表执行的操作。

您的第二种方法是实现目标的 pythonic 方法。


查看完整回答
反对 回复 2023-03-08
?
FFIVE

TA贡献1797条经验 获得超6个赞

  1. 为什么最初的代码看起来最合乎逻辑、最有效,却没有产生预期的结果?

建议不要在遍历列表时更改列表。这是因为它正在迭代初始列表的视图,并且该视图将与原始视图不同。

  1. 达到预期结果的最佳“Pythonic”方式是什么?

你的第二次尝试。但我会使用更好的命名约定,你的理解可以结合起来,因为你只是在第一个中将它们设为小写:

word_list = input_file.read().strip().split(' ')
filtered_word_list = [word.lower() for word in word_list if len(word) > 1]


查看完整回答
反对 回复 2023-03-08
?
千巷猫影

TA贡献1829条经验 获得超7个赞

第二次尝试是最pythonic的。第一个仍然可以通过以下方式实现:


filename = 'sample.txt'


with open(filename) as input_file:

    word_list = input_file.read().strip().split(' ')


word_list = [word.lower() for word in word_list]


for word in word_list:

    if len(word) == 1:

        word_list.remove(word)


print(word_list)


查看完整回答
反对 回复 2023-03-08
  • 4 回答
  • 0 关注
  • 97 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信