python-internals

Why do two identical lists have a different memory footprint?

妖精的绣舞 提交于 2019-11-27 11:30:48
I created two lists l1 and l2 , but each one with a different creation method: import sys l1 = [None] * 10 l2 = [None for _ in range(10)] print('Size of l1 =', sys.getsizeof(l1)) print('Size of l2 =', sys.getsizeof(l2)) But the output surprised me: Size of l1 = 144 Size of l2 = 192 The list created with a list comprehension is a bigger size in memory, but the two lists are identical in Python otherwise. Why is that? Is this some CPython internal thing, or some other explanation? When you write [None] * 10 , Python knows that it will need a list of exactly 10 objects, so it allocates exactly

Why is str.translate much faster in Python 3.5 compared to Python 3.4?

久未见 提交于 2019-11-27 11:24:51
问题 I was trying to remove unwanted characters from a given string using text.translate() in Python 3.4. The minimal code is: import sys s = 'abcde12345@#@$#%$' mapper = dict.fromkeys(i for i in range(sys.maxunicode) if chr(i) in '@#$') print(s.translate(mapper)) It works as expected. However the same program when executed in Python 3.4 and Python 3.5 gives a large difference. The code to calculate timings is python3 -m timeit -s "import sys;s = 'abcde12345@#@$#%$'*1000 ; mapper = dict.fromkeys(i

Does Python optimize away a variable that's only used as a return value?

纵然是瞬间 提交于 2019-11-27 10:37:31
问题 Is there any ultimate difference between the following two code snippets? The first assigns a value to a variable in a function and then returns that variable. The second function just returns the value directly. Does Python turn them into equivalent bytecode? Is one of them faster? Case 1 : def func(): a = 42 return a Case 2 : def func(): return 42 回答1: No, it doesn't . The compilation to CPython byte code is only passed through a small peephole optimizer that is designed to do only basic

Why are Python's arrays slow?

谁都会走 提交于 2019-11-27 09:38:27
问题 I expected array.array to be faster than lists, as arrays seem to be unboxed. However, I get the following result: In [1]: import array In [2]: L = list(range(100000000)) In [3]: A = array.array('l', range(100000000)) In [4]: %timeit sum(L) 1 loop, best of 3: 667 ms per loop In [5]: %timeit sum(A) 1 loop, best of 3: 1.41 s per loop In [6]: %timeit sum(L) 1 loop, best of 3: 627 ms per loop In [7]: %timeit sum(A) 1 loop, best of 3: 1.39 s per loop What could be the cause of such a difference?

Are list comprehensions syntactic sugar for `list(generator expression)` in Python 3?

大城市里の小女人 提交于 2019-11-27 09:23:55
In Python 3, is a list comprehension simply syntactic sugar for a generator expression fed into the list function? e.g. is the following code: squares = [x**2 for x in range(1000)] actually converted in the background into the following? squares = list(x**2 for x in range(1000)) I know the output is identical, and Python 3 fixes the surprising side-effects to surrounding namespaces that list comprehensions had, but in terms of what the CPython interpreter does under the hood, is the former converted to the latter, or are there any difference in how the code gets executed? Background I found

How is super() in Python 3 implemented?

元气小坏坏 提交于 2019-11-27 09:14:57
I'm wondering how is the new super in Python 3 implemented. This question was born in my head after I have made a small example and I got a strange error. I'm using Pyutilib Component architecture (PCA) and I've made my custom metaclass to drive the creation of another class: from pyutilib.component.core import implements, SingletonPlugin, PluginMeta, Interface class IPass(Interface): pass class __MetaPlugin(PluginMeta): def __new__(cls, name, baseClasses, classdict): print(cls, name, baseClasses, classdict) if baseClasses: baseClasses += (SingletonPlugin,) return PluginMeta.__new__(cls, name,

What does “del” do exactly?

感情迁移 提交于 2019-11-27 08:38:28
Here is my code: from memory_profiler import profile @profile def mess_with_memory(): huge_list = range(20000000) del huge_list print "why this kolaveri di?" This is what the output is, when I ran it from interpreter: Line # Mem usage Increment Line Contents 3 7.0 MiB 0.0 MiB @profile 4 def mess_with_memory(): 5 6 628.5 MiB 621.5 MiB huge_list = range(20000000) 7 476.0 MiB -152.6 MiB del huge_list 8 476.0 MiB 0.0 MiB print "why this kolaveri di" If you notice the output, creating the huge list consumed 621.5 MB while deleting it just freed up 152.6 MB. When i checked the docs , I found the

Why is True returned when checking if an empty string is in another?

不问归期 提交于 2019-11-27 08:34:54
My limited brain cannot understand why this happens: >>> print '' in 'lolsome' True In PHP, a equivalent comparison returns false: var_dump(strpos('', 'lolsome')); From the documentation : For the Unicode and string types, x in y is true if and only if x is a substring of y . An equivalent test is y.find(x) != -1 . Note, x and y need not be the same type; consequently, u'ab' in 'abc' will return True . Empty strings are always considered to be a substring of any other string, so "" in "abc" will return True . From looking at your print call, you're using 2.x. To go deeper, look at the bytecode

Python eval: is it still dangerous if I disable builtins and attribute access?

我的未来我决定 提交于 2019-11-27 07:05:10
We all know that eval is dangerous , even if you hide dangerous functions, because you can use Python's introspection features to dig down into things and re-extract them. For example, even if you delete __builtins__ , you can retrieve them with [c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__ However, every example I've seen of this uses attribute access. What if I disable all builtins, and disable attribute access (by tokenizing the input with a Python tokenizer and rejecting it if it has an attribute access token)? And before

why does sys.stdout = None work?

穿精又带淫゛_ 提交于 2019-11-27 06:57:35
问题 i can silence and restore sys.stdout this way: import sys sys.stdout = None print('hello') # does not write to stdout sys.stdout = sys.__stdout__ print('hello') # writes to stdout i know i'd better be using contextlib.redirect_stdout which probably does something similar but my question is: why does the above code work? i'd have assumed python would call things like sys.stdout.write() so whatever i replace sys.stdout with should have a write method (like e.g. io.StringIO) at least. 回答1: print