【问题标题】:Standard loop works when list comprehension does not当列表理解不起作用时,标准循环起作用
【发布时间】:2021-06-11 13:57:34
【问题描述】:

为什么下面的代码在我使用列表推导的地方不起作用,但常用的方法却可以?

exams = [1,2,3,1,2,3,4,1,5,1]
repeatedExams = []

# EXCPECTED OUPUT
# repeatedExams = [1,2,3]

# IF I USE repeatedExams.append(i)
repeatedExams = [repeatedExams.append(i) for i in exams if (exams.count(i)>1) and (i not in repeatedExams)]
    # OUTPUT 
    # repeatedExams = [None,None,None]

# IF I ONLY USE i
repeatedExams = [i for i in exams if (exams.count(i)>1) and (i not in repeatedExams)]
    # OUTPUT
    # repeatedExams = [1,2,3,1,2,3,4,1,5,1]

# WORK 
for i in exams:
    if exams.count(i) > 1 and i not in repeatedExams:
        repeatedExams.append(i)

    # OUTPUT
    # repeatedExams = [1,2,3]

【问题讨论】:

  • 将推导式append 列出为您的新列表;这就是他们的全部目的。 append 不返回任何内容,因此您的第一种方法不起作用。
  • 这能回答你的问题吗? Why does append() always return None in Python?
  • list(set([x for x in exams if exams.count(x)>1]))
  • 感谢 @usuario12339314 的需要,它运行良好。

标签: python list output list-comprehension


【解决方案1】:

list.append() 返回无

Comprehension 为您返回一个集合;你不需要预先定义一个

当你正在构建一个时,你不应该使用它,所以理解中的not in repeatedExams 不会做你想做的事


如果要计算重复次数,请使用计数器

from collections import Counter

exams = [1,2,3,1,2,3,4,1,5,1]
c = Counter(exams)
repeatedExams = [k for k,v in c.items() if v > 1]

【讨论】:

    【解决方案2】:

    列表解析语法告诉 Python 获取一个可迭代对象,并为该可迭代对象的每个元素计算一个表达式,然后根据该表达式返回的所有结果构建一个列表。 append 是所谓的“就地”运算符。这意味着它的操作不是通过返回结果,而是通过修改关联的对象。 inplace 运算符的实际值一般为None。例如,repeatedExams.append(i) 修改对象 repeatedExamsrepeatedExams 的修改版本现在存储在原来的repeatedExams 所在的位置,repeatedExams.append(i) 返回None。然后,您的语法将所有这些 Nones 存储在一个列表中。

    这样做可能会提供信息

    for i in exams:
        if (exams.count(i)>1) and (i not in repeatedExams):
            print(repeatedExams.append(i))
    

    看看你会得到什么。

    【讨论】:

      【解决方案3】:

      试试这个 -

      repeatedExams = [i for i in exams if exams.count(i)>1] 
      repeatedExams = set(repeatedExams)
      

      或者-

      repeatedExams = set([i for i in exams if exams.count(i)>1])
      

      【讨论】:

      • 这对您有帮助吗?
      【解决方案4】:

      如果你真的想使用列表推导,那么你需要将循环分成两个步骤:

      # Keep only repetated elements
      repeatedExams = [i for i in exams if exams.count(i)>1] 
      # Remove duplicates of repeated elements       
      repeatedExams = set(repeatedExams)
      

      【讨论】:

      • 使用set 来避免第二个列表理解。
      • @user12339314 这将删除重复项,而不是计算它们
      • 这个答案有二次运行时间,顺便说一句
      • 我知道 :) 我只是将所有内容都插入到列表推导中。
      • ... for i in repeatedExams if i not in repeatedExams 这不就是一个昂贵的空操作吗?
      【解决方案5】:
      repeatedExams = {exam for exam in exams if exams.count(exam)>1}
      

      类似于 user16198685 的回答,但 [] 括号和 'set()' 是多余的

      exam for exam in exams if exams.count(exam)>1 是一个生成器 set comprehension 将生成器作为参数,以及 listcomps。所以set([])括号可以换成'{}'

      【讨论】:

        猜你喜欢
        • 2022-12-10
        • 1970-01-01
        • 2016-11-01
        • 2012-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多