Android RecyclerView Sample交互设计:如何优雅处理列表项点击事件
2026/8/10 17:36:20
RaggedTensor 完全支持Python风格的多维索引/切片,但遵循一个核心限制:
✅ 允许对「均匀维度(最外层,行数固定)」做任意索引/切片;
✅ 允许对「不规则维度(行内可变长度)」做切片(如取前N个、最后N个元素);
❌ 禁止对「不规则维度做固定位置索引」(如强行取所有行的第3个元素)—— 因行长度不同,部分行无该位置,TF无法确定处理逻辑(报错/补默认值/删行均不明确)。
importtensorflowastf# 二维RaggedTensor(文本序列)queries=tf.ragged.constant([['Who','is','George','Washington'],# 行0:4个元素['What','is','the','weather','tomorrow'],# 行1:5个元素['Goodnight']])# 行2:1个元素# 三维RaggedTensor(嵌套数值序列)rt_3d=tf.ragged.constant([[[1,2,3],[4]],# 行0:2个子列表[[5],[],[6]],# 行1:3个子列表[[7]],# 行2:1个子列表[[8,9],[10]]])# 行3:2个子列表# 取第1行(索引从0开始):返回1D普通Tensor(该行元素无不规则性)print("queries[1] =",queries[1])结果:
tf.Tensor([b'What' b'is' b'the' b'weather' b'tomorrow'], shape=(5,), dtype=string)✅ 逻辑:最外层是均匀维度(固定3行),索引单一行返回该行的密集Tensor(无不规则结构)。
# 取第1行第2个元素:先定位行(均匀维度),再索引该行的固定位置(该行存在该位置)print("queries[1, 2] =",queries[1,2])结果:
tf.Tensor(b'the', shape=(), dtype=string)✅ 逻辑:仅对「某一行的固定位置」索引(而非所有行),该行有该位置,因此合法。
# 取第1行及以后的所有行:返回二维RaggedTensorprint("queries[1:] =",queries[1:])结果:
<tf.RaggedTensor [[b'What', b'is', b'the', b'weather', b'tomorrow'], [b'Goodnight']]>✅ 逻辑:均匀维度的切片,保留剩余行的不规则结构。
# 所有行的前3个元素:行内切片,不足3个的保留全部(如行2仅1个)print("queries[:, :3] =",queries[:,:3])# 所有行的最后2个元素:行内切片,不足2个的保留全部(如行2仅1个)print("queries[:, -2:] =",queries[:,-2:])结果:
queries[:, :3] = <tf.RaggedTensor [[b'Who', b'is', b'George'], [b'What', b'is', b'the'], [b'Goodnight']]> queries[:, -2:] = <tf.RaggedTensor [[b'George', b'Washington'], [b'weather', b'tomorrow'], [b'Goodnight']]>✅ 逻辑:对不规则维度做切片(而非固定位置索引),TF会按每行的实际长度处理(不足则保留全部),结果仍为RaggedTensor。
# 取第1行:返回二维RaggedTensor(保留该行的嵌套不规则结构)print("rt_3d[1] =",rt_3d[1])结果:
<tf.RaggedTensor [[5], [], [6]]>✅ 逻辑:三维RaggedTensor的最外层是均匀维度(4行),索引单一行返回二维RaggedTensor。
# 取第3行第0个子列表:先定位行(均匀维度),再定位该行的子列表(该行存在该子列表)print("rt_3d[3, 0] =",rt_3d[3,0])结果:
tf.Tensor([8 9], shape=(2,), dtype=int32)✅ 逻辑:仅针对某一行的子列表索引,该行有该子列表,合法。
# 所有行的第1~3个子列表(切片):返回三维RaggedTensorprint("rt_3d[:, 1:3] =",rt_3d[:,1:3])# 所有行的最后1个子列表(切片):返回三维RaggedTensorprint("rt_3d[:, -1:] =",rt_3d[:,-1:])结果:
rt_3d[:, 1:3] = <tf.RaggedTensor [[[4]], [[], [6]], [], [[10]]]> rt_3d[:, -1:] = <tf.RaggedTensor [[[4]], [[6]], [[7]], [[10]]]>✅ 逻辑:对嵌套的不规则维度做切片,TF自动处理每行的子列表数量(无则返回空)。
# ❌ 错误:尝试取所有行的第3个元素(不规则维度的固定位置索引)try:print(queries[:,3])exceptExceptionase:print("报错:",e)报错结果:
报错: Cannot index into an inner ragged dimension.TF 拒绝该操作的核心原因:
| 操作类型 | 示例 | 是否允许 | 原因 |
|---|---|---|---|
| 均匀维度索引 | queries[1] | ✅ | 最外层行数固定,无模糊性 |
| 单一行的行内索引 | queries[1, 2] | ✅ | 仅针对某一行,该行有该位置 |
| 不规则维度切片 | queries[:, :3] | ✅ | 切片按每行实际长度处理,无模糊性 |
| 所有行的固定列索引 | queries[:, 3] | ❌ | 部分行无该位置,处理逻辑不明确 |
| 三维嵌套固定位置索引 | rt_3d[:, 1] | ❌ | 部分行无该子列表,处理逻辑不明确 |
若业务需要取所有行的第N个元素(允许部分行无该元素),可通过以下方式实现:
# 方案:将RaggedTensor转密集张量(补默认值),再索引dense_queries=queries.to_tensor(default_value=b'')# 补空字符串print("所有行的第3个元素(补默认值):",dense_queries[:,3])结果:
所有行的第3个元素(补默认值): tf.Tensor([b'Washington' b'weather' b''], shape=(3,), dtype=string)✅ 逻辑:先补默认值转为密集张量(消除不规则性),再索引固定列,代价是引入冗余的默认值。
索引规则:
避坑关键:
结果类型:
RaggedTensor的索引设计既兼容Python习惯,又规避了“不规则维度固定索引”的模糊性,是处理可变长度数据的安全方案。