如果我使用列表检查成员资格与使用 csv.reader 对象检查成员资格,我会得到不同的结果。 下面使用 unittest 模块。
成员(member)资格的 csv.reader 测试
with open("file.tab", 'rb') as f:
reader = csv.reader(f, delimiter='\t')
self.assertTrue(['1', '2', '3', '4'] in reader)
self.assertTrue(['2', '3', '4', '5'] in reader)
self.assertTrue(['3', '4', '5', '6'] in reader)
成员列表测试
with open("file.tab", 'rb') as f:
reader = csv.reader(f, delimiter='\t')
reader = [record for record in reader]
self.assertTrue(['1', '2', '3', '4'] in reader)
self.assertTrue(['2', '3', '4', '5'] in reader)
self.assertTrue(['3', '4', '5', '6'] in reader)
我知道 file.tab 包含我正在测试的三个记录的条目,但第三个断言在使用 csv.reader 时出现“False is not true”并在使用列表时通过。
csv.reader 是一个生成器; docs没有明确说,但因为我可以用尽它,我认为这意味着它是一个发电机。我的想法是这可能是原因,但以下测试只打印 true:
x = xrange(5)
for m in range(5):
for n in range(5):
print m in x
print n in x
这让我觉得使用生成器测试成员资格没有问题。
为什么当我使用 csv.reader 时第三个 assert 语句的计算结果与我使用列表时不同?
最佳答案
你运气不好 -- xrange
实际上不是一个生成器,而是它自己的一种特殊类型,它的行为是惰性的,因此可以让你误以为它是一个生成器。
>>> x = xrange(10)
>>> 5 in x
True
>>> 5 in x
True
但是
>>> it = iter(range(10))
>>> 5 in it
True
>>> 5 in it
False
所以您的逻辑是正确的:reader
实例可以用完,但列表不能,这就是为什么成员测试可以根据内容返回不同答案的原因。请注意,虽然成员资格测试可能会短路,因此在出现积极结果的情况下它们不必耗尽:
>>> it = iter(range(10))
>>> 3 in it
True
>>> next(it)
4
关于python - 成员资格测试结果与 list 和 csv.reader 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21027386/