迭代类对象列表的“pythonic”方法

9

我有一个名为test_cases的类对象列表。每个对象都有一个名为ident的属性。 我想要遍历列表中的所有对象,并对ident下的值执行某些操作。

这是我的代码:

class TestCase:
    def __init__(self, title, ident, description):
        self.title = title
        self.ident = ident
        self.description = description

test_cases = []
test_cases.append(TestCase(**tc_dict))

i = 0
while i != len(test_cases):
    print(test_cases[i].ident)
    i += 1

这个方法可以正常工作,但我想问一下,是否有更符合Python编程风格的方法。


1
你能提供test_cases的值吗?(列表的一个示例) - Stavros Avramidis
1
奇妙的是,我在过去的SO问题中找不到关于这个的记录;尽管如此,它已经被广泛讨论了,例如来自PyCon 2013的这次演讲。https://nedbatchelder.com/text/iter.html - Arya McCarthy
2个回答

16

使用 for 循环直接迭代对象(而不是迭代它们的索引):

for test_case in test_cases:
    print test_case.ident

这是一种通用的方法,在大多数情况下,当您想要遍历对象时应该使用它。它在这里运行得非常完美,并且可能是理想的解决方案。

如果您确实需要索引,则应使用enumerate()

for index, test_case in enumerate(test_cases):
    print index, test_case.ident

它仍在循环对象,但同时也从enumerate接收它们的索引。


对于你特定的用例,还有另一种选择。如果你有大量的对象,逐个打印它们可能会很慢(调用print相当昂贵)。如果性能成为问题,你可以使用str.join事先连接值,然后一次性将其全部打印出来:

print '\n'.join(tc.ident for tc in test_cases)

个人建议优先选择第一种方法,仅当您需要打印 大量 的内容并且能够亲眼看到性能问题时才考虑使用后者。


不错,Markus。我猜在print '\n'.join(tc.ident for tc in test_cases)中添加一个检查 hasattr(object, 'attribute') 将是安全的。 - Amitkumar Karnik
你的列表里最好不要随意放置不同类型的对象。OP的例子中有TestCase类,所以如果你混入了与TestCase不兼容的对象,很可能会引发错误。 - Markus Meskanen

3

首先,你可以用for循环替换while循环

for i in range(len(test_cases)):
    print test_cases[i].indent

然而,在Python中使用索引循环并通过该索引访问元素通常是一种不好的代码习惯。更好的做法是直接循环遍历元素。

for test_case in test_cases:
    print test_case.indent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接