What does locals()['_[1]'] mean in Python?

后端 未结 4 568
一向
一向 2021-01-11 12:04

I saw a one liner code that is claimed to remove duplicates from a sequence:

u = [x for x in seq if x not in locals()[\'_[1]\']]

I tried th

相关标签:
4条回答
  • 2021-01-11 12:45

    locals()['_[1]'] is a way to access a reference to list comprehension (or generator) current result inside that list comprehension.

    It is quite an evil, but can produce funny results:

    >> [list(locals()['_[1]']) for x in range(3)]
    [[], [[]], [[], [[]]]]
    

    See more details here: the-secret-name-of-list-comprehensions.

    0 讨论(0)
  • 2021-01-11 12:45

    locals() from Python docs:

    Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

    I can't see why locals() is used in that one liner, maybe it's not as general as you want.

    If you're trying to remove duplicates from a list I think the best choice is convert it to a set:

    In [2]: l = [1,1,3,4,2,4,6]
    In [4]: set(l)
    Out[4]: set([1, 2, 3, 4, 6])
    

    If you want a list again:

    In [5]: list(set(l))
    Out[5]: [1, 2, 3, 4, 6]
    
    0 讨论(0)
  • 2021-01-11 12:46

    It is a temporary name used in a list comprehension by Python 2.6 and earlier. Python 2.7 and Python 3.x fixed this wart: the list being created is no longer accessible until creation has finished.

    Or in short it was an implementation detail that nobody should ever have relied on.

    Here you can see that Python 2.7 leaves locals() unchanged while Python 2.6 creates a short live temporary:

    Python 2.7.2 (default, Jan  5 2012, 16:24:09)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def foo():
            t = [list(locals().keys()) for x in range(1) ]
            print(locals())
            print(t[0])
    
    >>> foo()
    {'x': 0, 't': [['x']]}
    ['x']
    >>>
    
    Python 2.6.7 (r267:88850, Jan  5 2012, 16:18:48)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def foo():
            t = [list(locals().keys()) for x in range(1) ]
            print(locals())
            print(t[0])
    
    >>> foo()
    {'x': 0, 't': [['_[1]', 'x']]}
    ['_[1]', 'x']
    >>>
    

    Python 3.x introduces a new short lived temporary for list comprehensions called .0. Don't be tempted to use that for anything either. Also the whole list comprehension runs in a separate namespace so the loop variables aren't accessible outside the loop either:

    Python 3.2 (r32:88445, Jan  5 2012, 16:29:57)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def foo():
            t = [list(locals().keys()) for x in range(1) ]
            print(locals())
            print(t[0])
    
    >>> foo()
    {'t': [['.0', 'x']]}
    ['.0', 'x']
    
    0 讨论(0)
  • 2021-01-11 12:48

    Wow! That's nastily cryptic code. Took a bit of research to find the answer.

    Basically the list comprehension is building a new list. It names this temporary list _[1]. The locals() part is just using the locals() dictionary to look up that name, as it's not accessible otherwise. So that line is saying...

    [x for x in seq if x not in this_list]
    

    Cryptic.

    The found information on this here

    0 讨论(0)
提交回复
热议问题