list literal 和 list comprehension 的行为不同
list literal and list comprehension behaving differently
我在使用 Python 3.7 时遇到了一个非常奇怪的问题。具体来说,我有一个函数可以获取文档 ID 列表,以及 returns 它们对应的维基百科文档。奇怪的是,如果我按照我的意愿传入一个列表理解,它 returns 什么都没有,但是如果我传入一个具有完全相同值的列表文字,它就会以某种方式起作用。请注意,这是使用 pdb,在交互式提示中,当您键入 interact
:
时它会打开
如果我运行列表理解,我得到这个列表:
>>> [x[0] for x in truncated]
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
如果我 运行 使用此列表文字的查询,它将起作用(数据 t运行 为简洁起见):
>>> self._db.query_ids([3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007])
[(1955046, 'Hairy_nightshade', 'Hairy nightshade is a common name for...')]
但是如果我将这两个表达式结合起来,它 returns 什么都没有:
>>> self._db.query_ids([x[0] for x in truncated])
[]
被调用的实际函数没有副作用,它只是查询数据库,因此它不会以任何方式在调用之间发生变化:
def query_ids(self, ids):
"""
Returns the tokens for each document with the given ID
"""
result = self.conn.execute(
'SELECT doc_id, document, group_concat(tokens, " ") FROM doc WHERE doc_id in ({}) GROUP BY doc_id'.format(
', '.join(['?'] * len(ids))), ids)
data = result.fetchall()
return data
这怎么可能?
如果我将 print(ids)
添加到 query_ids
函数的第一行,两次打印的 ID 列表相同,但它仍然不适用于列表理解:
(Pdb) self._db.query_ids([x[0] for x in truncated])
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
[]
(Pdb) self._db.query_ids([3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007])
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
[(1955046, 'Hairy_nightshade', 'Hairy nightshade is a common name for several plants and may refer to...')]
这是一个奇怪的错误,但我相信我已经解决了。
问题不在于 truncated
的类型,它是一个列表,而是该列表的内容是 numpy int64 类型,不是 python整数:
(Pdb) !a = [x[0] for x in truncated]
(Pdb) type(a)
<class 'list'>
(Pdb) type(a[0])
<class 'numpy.int64'>
当这个 numpy.int64
的列表被传递到数据库查询时,它们被忽略了,因为 Python sqlite3 API 不知道如何处理 non-native Python 类型:https://docs.python.org/3/library/sqlite3.html#using-adapters-to-store-additional-python-types-in-sqlite-databases
The following Python types can thus be sent to SQLite without any problem: None, int, float, str, bytes
因此,当我将数据转换为原生 Python 整数时,它起作用了:
(Pdb) self._db.query_ids([int(x[0]) for x in truncated])
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
[(1955046, 'Hairy_nightshade', 'Hairy nightshade is a common name for several plants and may refer to ')]
我在使用 Python 3.7 时遇到了一个非常奇怪的问题。具体来说,我有一个函数可以获取文档 ID 列表,以及 returns 它们对应的维基百科文档。奇怪的是,如果我按照我的意愿传入一个列表理解,它 returns 什么都没有,但是如果我传入一个具有完全相同值的列表文字,它就会以某种方式起作用。请注意,这是使用 pdb,在交互式提示中,当您键入 interact
:
如果我运行列表理解,我得到这个列表:
>>> [x[0] for x in truncated]
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
如果我 运行 使用此列表文字的查询,它将起作用(数据 t运行 为简洁起见):
>>> self._db.query_ids([3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007])
[(1955046, 'Hairy_nightshade', 'Hairy nightshade is a common name for...')]
但是如果我将这两个表达式结合起来,它 returns 什么都没有:
>>> self._db.query_ids([x[0] for x in truncated])
[]
被调用的实际函数没有副作用,它只是查询数据库,因此它不会以任何方式在调用之间发生变化:
def query_ids(self, ids):
"""
Returns the tokens for each document with the given ID
"""
result = self.conn.execute(
'SELECT doc_id, document, group_concat(tokens, " ") FROM doc WHERE doc_id in ({}) GROUP BY doc_id'.format(
', '.join(['?'] * len(ids))), ids)
data = result.fetchall()
return data
这怎么可能?
如果我将 print(ids)
添加到 query_ids
函数的第一行,两次打印的 ID 列表相同,但它仍然不适用于列表理解:
(Pdb) self._db.query_ids([x[0] for x in truncated])
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
[]
(Pdb) self._db.query_ids([3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007])
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
[(1955046, 'Hairy_nightshade', 'Hairy nightshade is a common name for several plants and may refer to...')]
这是一个奇怪的错误,但我相信我已经解决了。
问题不在于 truncated
的类型,它是一个列表,而是该列表的内容是 numpy int64 类型,不是 python整数:
(Pdb) !a = [x[0] for x in truncated]
(Pdb) type(a)
<class 'list'>
(Pdb) type(a[0])
<class 'numpy.int64'>
当这个 numpy.int64
的列表被传递到数据库查询时,它们被忽略了,因为 Python sqlite3 API 不知道如何处理 non-native Python 类型:https://docs.python.org/3/library/sqlite3.html#using-adapters-to-store-additional-python-types-in-sqlite-databases
The following Python types can thus be sent to SQLite without any problem: None, int, float, str, bytes
因此,当我将数据转换为原生 Python 整数时,它起作用了:
(Pdb) self._db.query_ids([int(x[0]) for x in truncated])
[3553957, 4480571, 4686346, 1955046, 4476254, 4510002, 3941950, 2991560, 5314256, 3949007]
[(1955046, 'Hairy_nightshade', 'Hairy nightshade is a common name for several plants and may refer to ')]