16

我可以在列表中对列表进行排序时访问它吗list.sort()

b = ['b', 'e', 'f', 'd', 'c', 'g', 'a']
f = 'check this'

def m(i):
    print i, b, f
    return None

b.sort(key=m)
print b

这返回

b [] check this
e [] check this
f [] check this
d [] check this
c [] check this
g [] check this
a [] check this

请注意,列表的各个项目b被发送到 function m。但是在mlistb是空的,但是它可以看到与flist 具有相同范围的变量b。为什么函数m打印b[]

4

2 回答 2

14

查看源代码(CPython,可能其他实现的不同行为)脚本的奇怪输出变得很明显:

/* The list is temporarily made empty, so that mutations performed
 * by comparison functions can't affect the slice of memory we're
 * sorting (allowing mutations during sorting is a core-dump
 * factory, since ob_item may change).
 */
saved_ob_size = Py_SIZE(self);
saved_ob_item = self->ob_item;
saved_allocated = self->allocated;
Py_SET_SIZE(self, 0);

评论说明了一切:当您开始排序时,列表被清空。好吧,在外部观察者的眼中,它是“空的”。

我很喜欢“核心转储工厂”这个词。


也比较一下:

b = ['b','e','f','d','c','g','a']
f = 'check this'


def m(i):
    print i, b, f
    return None

b = sorted(b, key= m)
print b
于 2014-03-27T04:22:52.043 回答
4

这是您通常不能依赖的东西 - 不仅仅是列表 - 除非您正在使用的方法的文档另有明确说明。访问处于中间状态的对象——即,在一些迭代开始之后,但在它完成之前——是并发代码经常遇到的问题。你发现了一个罕见的非并发情况,但建议是一样的:避免这种情况。中间状态不保证对您有意义,也不保证根据该对象的规则是“有效”状态(当它往往被称为“不一致”状态时)。

于 2014-03-27T04:32:02.893 回答