【问题标题】:Is there a python 3 for loop one-liner that doesn't produce a list? [duplicate]是否有 python 3 for loop one-liner 不产生列表? [复制]
【发布时间】:2020-10-07 23:24:39
【问题描述】:

我是 python 3 的新手,我的谷歌搜索一直没有成效。有没有办法写这个:

for x in range(10):
  print(x) 

这样:

print(x) for x in range(10)

我不想像arr = [x for x in X] 列表理解语法那样返回一个列表。

编辑:我实际上并不在涉及 print() 的那个特定案例中,我对一个通用的 Python 语法结构感兴趣

method(element) for element in list

【问题讨论】:

  • 我们通常和list-comprehension一起使用。
  • print("\n".join(map(str, range(10))))
  • 感谢 dawg,但我真的在寻找与 js foreach 方法大致相似且真正 Python 的东西。
  • print("\n".join([str(x) for x in range(10)]))
  • 不,不只是一个单行 for 循环。理解构造产生相应的容器、列表、字典、集合或生成器对象。 map 返回一个迭代器。只需使用 for 循环。 For循环是pythonic

标签: python python-3.x list-comprehension


【解决方案1】:

不,没有。除非你认为这是一个单行:

for x in range(6): print(x) 

但没有理由这样做。

【讨论】:

    【解决方案2】:

    为您的具体情况打印 6 的范围:

    print(*range(6), sep='\n')
    

    这不是 for 循环,但 @Boris 是正确的。

    【讨论】:

      【解决方案3】:

      看起来您正在寻找类似map 的内容。如果你调用的函数返回None,那就不会太贵了。

      Map 将返回一个迭代器,因此您只是在尝试使用它。 一种方法是:

      list(map(print, range(6)))
      

      如果您不想存储实际的列表元素,则使用零长度双端队列。

      from collections import deque
      
      deque(map(print, range(6)), maxlen=0)
      

      【讨论】:

      • 这可能是一个类似的讨论。 stackoverflow.com/a/50938015/5208670
      • 使用list(map()) 与使用列表推导相同。它产生一个列表。
      • @boris。很公平。我试图强调 map 的概念,需要一个迭代器来使用它。
      • 这样使用地图打印是不好的风格
      • @VictorUriarte 当然,但 map 不应与任何通用函数一起使用。它应该与没有副作用的纯函数一起使用。这基本上是我一直试图提出的观点:列表推导、映射等不仅仅是“单线循环”,它们的存在是为了便于在具有纯函数的任意迭代上表达映射/过滤操作,而不是通用替换 for 语句以节省空间
      【解决方案4】:

      您正在寻找的是一个返回生成器对象的生成器表达式。

      print(i for i in range(10)) #<generator object <genexpr> at 0x7f3a5baacdb0>
      

      查看值

      print(*(i for i in range(10))) # 0 1 2 3 4 5 6 7 8 9
      

      优点:

      • 内存效率极高。
      • 惰性求值 - 仅根据需要生成下一个元素。

      缺点:

      • 可以一直迭代,直到停止迭代,之后就不能再重复了。
      • 不能像列表一样被索引。

      希望这会有所帮助!

      【讨论】:

      • 另外,生成器对象可能不会像列表一样被切片,但您可以使用 itertools 库中的 islice() 来应用切片。为了重申一个生成器对象,可以使用 itertools 中的 tee() 函数创建相同的新副本,该函数返回可以迭代的对象的 n 个副本,每个副本一次
      • 这是否仍会产生一个列表,该列表将作为其*args 传递给print
      • *args 被传递给 print 只是为了显示生成器包含的内容。它可以像一个列表一样玩。像 sum(generator obj) 给出与 sum(list) 相同的结果,前者在内存方面表现更好。
      • 这比列表推导没有任何优势,这里的关键是 print 不是推导结构的一部分。事实上,print(*(i for i in whatever)) 应该只是 print(*whatever)
      • @juanpa.arrivillaga,当然,但是一个包含 1000 个数字(88 字节)的生成器对象和一个包含 1000 个数字(9024 字节)的列表在占用多少内存方面差别很大。所以有一个重要的优势,这是众多优势之一,生成器支持 FP 范式,最终给开发者带来很多好处。尝试执行 sys.getsizeof(i for I in range(1000)) 并尝试对包含 1000 个数字的列表执行相同操作。
      猜你喜欢
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      • 2020-08-15
      相关资源
      最近更新 更多