假设如下:

>>> s = set([1, 2, 3])

我如何得到一个值(任何值)不做s.pop()?我希望将项目留在集合中,直到我确定可以删除它—只有在对另一个主机进行异步调用之后才能确定这一点。

又快又脏:

>>> elem = s.pop()
>>> s.add(elem)

但你知道更好的办法吗?理想情况是在常数时间内。


当前回答

我用的是我写的效用函数。它的名字有点误导,因为它暗示它可能是一个随机的项目或类似的东西。

def anyitem(iterable):
    try:
        return iter(iterable).next()
    except StopIteration:
        return None

其他回答

s.copy().pop()怎么样?我还没有计时,但应该可以,而且很简单。但是,它最适用于小集,因为它复制了整个集。

对于小型集合,我通常会创建类似这样的解析器/转换器方法

def convertSetToList(setName):
return list(setName)

然后我可以使用新的列表和访问索引号

userFields = convertSetToList(user)
name = request.json[userFields[0]]

作为一个列表,您将拥有所有其他可能需要使用的方法

我用的是我写的效用函数。它的名字有点误导,因为它暗示它可能是一个随机的项目或类似的东西。

def anyitem(iterable):
    try:
        return iter(iterable).next()
    except StopIteration:
        return None

如果你只想要第一个元素,试试这个: B = (a-set())).pop()

为了提供不同方法背后的时间图,考虑以下代码。 get()是我自定义添加到Python的setobject.c,只是一个pop(),没有删除元素。

from timeit import *

stats = ["for i in xrange(1000): iter(s).next()   ",
         "for i in xrange(1000): \n\tfor x in s: \n\t\tbreak",
         "for i in xrange(1000): s.add(s.pop())   ",
         "for i in xrange(1000): s.get()          "]

for stat in stats:
    t = Timer(stat, setup="s=set(range(100))")
    try:
        print "Time for %s:\t %f"%(stat, t.timeit(number=1000))
    except:
        t.print_exc()

输出结果为:

$ ./test_get.py
Time for for i in xrange(1000): iter(s).next()   :       0.433080
Time for for i in xrange(1000):
        for x in s:
                break:   0.148695
Time for for i in xrange(1000): s.add(s.pop())   :       0.317418
Time for for i in xrange(1000): s.get()          :       0.146673

这意味着for/break解决方案是最快的(有时比自定义get()解决方案还要快)。