我有一个列表,想通过一些计算制作一个新列表。 这样做时,我遇到了这个问题:
为什么pop()不能一次从列表中删除所有项目?
>>> a= list(range(20))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> [a.pop() for elem in a]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10]
>>> [a.pop() for elem in a]
[9, 8, 7, 6, 5]
>>> [a.pop() for elem in a]
[4, 3, 2]
>>> [a.pop() for elem in a]
[1]
我期望的是
>>> a= list(range(20))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> [a.pop() for elem in a]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
有人可以解释这种行为吗?
答案 0 :(得分:4)
循环for item in a
从0循环遍历索引,直到到达列表的末尾。在该循环中,您通过调用pop()
来减少列表长度。因此,如果列表是20个项目,则在循环浏览10个项目之后,列表的长度将变为10,并且循环将停止。您只能循环播放等于列表原始长度一半的次数。
因此,第一次20的一半是10。然后10的一半是5。然后5的一半是3(循环两次后仍未到达末尾),则列表长度为5-3 = 2一半是1。剩下的是长度为1的列表,[0]
。
另一个黄金法则的特殊情况是,在迭代列表时不要对其进行变异。
答案 1 :(得分:2)
如果您使用for循环运行相同的代码,而不使用列表推导,则会找到解释:
// user class
public partial class tempu
{
public int id { get; set; }
[StringLength(50)]
public string name { get; set; }
public List<tempd> tempds { get; set; }
}
// device class
public partial class tempd
{
public int? token { get; set; }
public int? uid { get; set; }
[StringLength(50)]
public string name { get; set; }
public int id { get; set; }
public tempu tempus { get; set; }
}
// context
modelBuilder.Entity<tempu>(entity =>
{
entity.ToTable("tempu");
});
//// this is do the mapping of one to many
modelBuilder.Entity<tempd>(entity =>
{
entity.ToTable("tempd")
.HasOne(p => p.tempus)
.WithMany(i => i.tempds)
.HasForeignKey(b => b.uid);
});
// linq query
var results = _context.tempu
.Where(t => t.tempds.Any(y => y.token == null)) //// this will check if device id can be null in any case,
.Include(s => s.tempds) //// this will do the join
.ToList();
// generated sql
SELECT [t].[id], [t].[name]
FROM [tempu] AS [t]
WHERE EXISTS (
SELECT 1
FROM [tempd] AS [y]
WHERE [y].[token] IS NULL AND ([t].[id] = [y].[uid]))
ORDER BY [t].[id]
输出将为
for ele in a:
print(ele)
print("Pop : ",a.pop())
因此,当您从同一列表中弹出元素时,这还会缩短该列表的大小。因此,它不会一次删除所有元素。
答案 2 :(得分:0)
现在说明行为,以获取您期望的结果
>>> [a.pop() for el in range(20)]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]