<p><code>del</code>不删除对象:它删除名称。如果多个名称引用同一对象,则其他名称将保持不变</p>
<p>取消绑定<code>i</code>循环变量对基础列表不起任何作用,而<code>i</code>只是在下一次迭代中被重新分配。必须删除实际的列表元素<code>v2[index_of_i]</code>,才能将其从列表中删除</p>
<p>为了能够安全地执行此操作,您需要替换原始列表或向后迭代列表的副本。您也可以向前迭代,但是索引需要格外小心,以确保它考虑前面删除的元素</p>
<p>其次<code>i.items()</code>上的循环是适得其反的。您不希望找到一个包含某个键且其中包含空列表的词典。您需要一个只有一个键的字典,因此不需要循环</p>
<pre><code>for k1, v1 in profiles_dict.items():
for k2, v2 in v1.items():
if type(v2) != list:
continue
v1[k2] = [i for i in v2 if len(i) > 1 or next(i.values())]
</code></pre>
<p>向后迭代将允许您保留原始列表对象:</p>
<pre><code>for k1, v1 in profiles_dict.items():
for k2, v2 in v1.items():
if type(v2) != list:
continue
n = len(v2) - 1 # capture before modifying
for i, e in enumerate(reversed(v2)):
if len(e) == 1 and not next(iter(e.values()))
del v2[n - i]
</code></pre>
<p>如果向前迭代,则必须复制列表才能正确执行,并对索引进行额外的簿记:</p>
<pre><code>for k1, v1 in profiles_dict.items():
for k2, v2 in v1.items():
if type(v2) != list:
continue
count = 0
for i, e in enumerate(v2[:]):
if len(e) == 1 and not next(iter(e.values()))
del v2[i - count]
count += 1
</code></pre>
<p>表达式<code>next(iter(...))</code>是一种常见的习惯用法,用于从只有一个元素但无法轻松索引的对象中获取单个元素,如<code>dict</code>或<code>set</code>。像<code>pop</code>这样的方法是破坏性的:如果只想检查元素,就必须将其放回原处<code>next(iter(...))</code>允许您查看集合</p>