On Monday 30 August 2010, it occurred to Tobias Weber to exclaim: > Hi, > whenever I type an "object literal" I'm unsure what optimisation will do > to it. > > def m(arg): > if arg & set([1,2,3]): > return 4 > > Is the set created every time the method is called? What about a > frozenset? Or tuple vs list? After how many calls per second does it pay > to save it at the module level? Would anybody else find this ugly?
That creates a list, and then calls "set" with the list as an argument. Every time, because that's what the code says: call "set" with a new list containing 1, 2, and 3. If you use a tuple instead of the list, the tuple can be loaded as a whole -- as tuples are immutable, it doesn't have to be re-created every time, it can be the same object. If you use a set literal instead of calling "set", the set is constructed directly, like a list would be. Details: >>> def m_l(arg): ... if arg & set([1,2,3]): ... return 4 ... >>> def m_t(arg): ... if arg & set((1,2,3)): ... return 4 ... >>> def m_s(arg): ... if arg & {1, 2, 3}: ... return 4 ... >>> from dis import dis >>> dis(m_l) 2 0 LOAD_FAST 0 (arg) 3 LOAD_GLOBAL 0 (set) 6 LOAD_CONST 1 (1) 9 LOAD_CONST 2 (2) 12 LOAD_CONST 3 (3) 15 BUILD_LIST 3 18 CALL_FUNCTION 1 21 BINARY_AND 22 POP_JUMP_IF_FALSE 29 3 25 LOAD_CONST 4 (4) 28 RETURN_VALUE >> 29 LOAD_CONST 0 (None) 32 RETURN_VALUE >>> dis(m_t) 2 0 LOAD_FAST 0 (arg) 3 LOAD_GLOBAL 0 (set) 6 LOAD_CONST 5 ((1, 2, 3)) 9 CALL_FUNCTION 1 12 BINARY_AND 13 POP_JUMP_IF_FALSE 20 3 16 LOAD_CONST 4 (4) 19 RETURN_VALUE >> 20 LOAD_CONST 0 (None) 23 RETURN_VALUE >>> dis(m_s) 2 0 LOAD_FAST 0 (arg) 3 LOAD_CONST 1 (1) 6 LOAD_CONST 2 (2) 9 LOAD_CONST 3 (3) 12 BUILD_SET 3 15 BINARY_AND 16 POP_JUMP_IF_FALSE 23 3 19 LOAD_CONST 4 (4) 22 RETURN_VALUE >> 23 LOAD_CONST 0 (None) 26 RETURN_VALUE >>> -- http://mail.python.org/mailman/listinfo/python-list