优雅的Pythonic简单循环解决方案

0 投票
2 回答
1069 浏览
提问于 2025-04-19 06:46

这个函数 bars 接受一个包含 Foo 对象的列表,然后返回这些对象的 bar 属性组成的列表。

 def bars(foos):
      bars = []
      for foo in foos:
          bars.append(foo.bar)
      return bars

我以前是用Java编程的,这种方法是我过去解决这个问题的方式。但我觉得在Python中,有一种更优雅的方法来解决这个问题。我该怎么做呢?

2 个回答

1

对于你的例子,@Korem 提出的列表推导是个很好的解决方案。

不过,这里有一个替代方案,适合你遇到以下情况时:

  • 先初始化一个空的序列
  • 在循环中往里面添加内容
  • 最后返回这个序列

但如果你需要做一些比较复杂的操作,不能简单地用表达式来表示(因为列表推导只允许用表达式,不允许用语句),你可以创建一个生成器函数

def bars(foos):
    for foo in foos:
        yield foo.bar

这里有两点需要注意:

  • 生成器函数不会返回一个序列,而是返回一个生成器。这个生成器需要通过迭代来使用。如果你想像使用序列那样(比如通过索引访问元素),你需要把它转换成一个序列,例如通过执行 list(bars(f))
>>> gen = bars(f)
>>> gen[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'generator' object has no attribute '__getitem__'
>>>
>>> list(gen)[0]
42
  • 一旦你迭代过这个生成器,它就会被耗尽:
>>> gen = bars(f)
>>> list(gen)
[42, 42, 42]
>>> list(gen)
[]
6

使用列表推导式

[foo.bar for foo in foos]

(你可以用def bars(foos):把它包起来,但我觉得不这样写更容易理解)

撰写回答