python - 成员资格测试结果与 list 和 csv.reader 不同

标签 python csv

如果我使用列表检查成员资格与使用 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/

相关文章:

python - Pandas read_csv() 适用于 Python 3 中的 CSV 文件,但在 Python 2 中返回 NaN

python - jupyter notebook 在 Mac 上不工作

php - 如何去除所有换行符以生成正确的 CSV?

mysql - 将 CSV 数据合并到现有表中

python - 如何绘制 seaborn ridge plot

php - 从对象数组的单列创建逗号分隔的字符串

excel - 为什么我的 VBA 宏在打开和关闭数百个 CSV 文件后停止?

Python xml.dom.minidom.parse() 函数忽略 DTD

python - 识别单元格是否包含 Word 中的方程式

Python - 解析字符串,已知结构