How to retrieve an element from a set without removing it?

前端 未结 14 2639
孤城傲影
孤城傲影 2020-12-07 07:17

Suppose the following:

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

How do I get a value (any value) out of s without doing s.pop()

14条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-07 08:04

    tl;dr

    for first_item in muh_set: break remains the optimal approach in Python 3.x. Curse you, Guido.

    y u do this

    Welcome to yet another set of Python 3.x timings, extrapolated from wr.'s excellent Python 2.x-specific response. Unlike AChampion's equally helpful Python 3.x-specific response, the timings below also time outlier solutions suggested above – including:

    • list(s)[0], John's novel sequence-based solution.
    • random.sample(s, 1), dF.'s eclectic RNG-based solution.

    Code Snippets for Great Joy

    Turn on, tune in, time it:

    from timeit import Timer
    
    stats = [
        "for i in range(1000): \n\tfor x in s: \n\t\tbreak",
        "for i in range(1000): next(iter(s))",
        "for i in range(1000): s.add(s.pop())",
        "for i in range(1000): list(s)[0]",
        "for i in range(1000): random.sample(s, 1)",
    ]
    
    for stat in stats:
        t = Timer(stat, setup="import random\ns=set(range(100))")
        try:
            print("Time for %s:\t %f"%(stat, t.timeit(number=1000)))
        except:
            t.print_exc()
    

    Quickly Obsoleted Timeless Timings

    Behold! Ordered by fastest to slowest snippets:

    $ ./test_get.py
    Time for for i in range(1000): 
        for x in s: 
            break:   0.249871
    Time for for i in range(1000): next(iter(s)):    0.526266
    Time for for i in range(1000): s.add(s.pop()):   0.658832
    Time for for i in range(1000): list(s)[0]:   4.117106
    Time for for i in range(1000): random.sample(s, 1):  21.851104
    

    Faceplants for the Whole Family

    Unsurprisingly, manual iteration remains at least twice as fast as the next fastest solution. Although the gap has decreased from the Bad Old Python 2.x days (in which manual iteration was at least four times as fast), it disappoints the PEP 20 zealot in me that the most verbose solution is the best. At least converting a set into a list just to extract the first element of the set is as horrible as expected. Thank Guido, may his light continue to guide us.

    Surprisingly, the RNG-based solution is absolutely horrible. List conversion is bad, but random really takes the awful-sauce cake. So much for the Random Number God.

    I just wish the amorphous They would PEP up a set.get_first() method for us already. If you're reading this, They: "Please. Do something."

提交回复
热议问题