python-internals

Unexpected Behavior of itertools.groupby

血红的双手。 提交于 2019-12-03 15:25:10
This is the observed behavior: In [4]: x = itertools.groupby(range(10), lambda x: True) In [5]: y = next(x) In [6]: next(x) --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-6-5e4e57af3a97> in <module>() ----> 1 next(x) StopIteration: In [7]: y Out[7]: (True, <itertools._grouper at 0x10a672e80>) In [8]: list(y[1]) Out[8]: [9] The expected output of list(y[1]) is [0,1,2,3,4,5,6,7,8,9] What's going on here? I observed this on cpython 3.4.2 , but others have seen this with cpython 3.5 and IronPython 2.9.9a0

Python string concatenation internal details

五迷三道 提交于 2019-12-03 14:20:11
Assume that we have a list of strings and we want to create a string by concatenating all element in this list. Something like this: def foo(str_lst): result = '' for element in str_lst: result += element return result Since strings are immutable objects, I expect that python creates a new str object and copy contents of result and element at each iteration. It makes O(M * N^2) time complexity, M is the length of each element and N is the size of the list. However, my experiment shows that it runs in linear time. N = 1000000 # 1 million str_lst = ['a' for _ in range(N)] foo(str_lst) # It takes

In-place custom object unpacking different behavior with __getitem__ python 3.5 vs python 3.6

a 夏天 提交于 2019-12-03 13:23:55
a follow-up question on this question : i ran the code below on python 3.5 and python 3.6 - with very different results: class Container: KEYS = ('a', 'b', 'c') def __init__(self, a=None, b=None, c=None): self.a = a self.b = b self.c = c def keys(self): return Container.KEYS def __getitem__(self, key): if key not in Container.KEYS: raise KeyError(key) return getattr(self, key) def __str__(self): # python 3.6 # return f'{self.__class__.__name__}(a={self.a}, b={self.b}, c={self.c})' # python 3.5 return ('{self.__class__.__name__}(a={self.a}, b={self.b}, ' 'c={self.c})').format(self=self) data0 =

Python method accessor creates new objects on each access?

99封情书 提交于 2019-12-03 12:21:20
When investigating for another question , I found the following: >>> class A: ... def m(self): return 42 ... >>> a = A() This was expected: >>> A.m == A.m True >>> a.m == a.m True But this I did not expect: >>> a.m is a.m False And especially not this: >>> A.m is A.m False Python seems to create new objects for each method access. Why am I seeing this behavior? I.e. what is the reason why it can't reuse one object per class and one per instance? Yes, Python creates new method objects for each access, because it builds a wrapper object to pass in self . This is called a bound method . Python

Python: which types support weak references?

丶灬走出姿态 提交于 2019-12-03 12:12:49
Code: from weakref import WeakSet se = WeakSet() se.add(1) Output: TypeError: cannot create weak reference to 'int' object Doc : Several built-in types such as list and dict do not directly support weak references but can add support through subclassing: ... Other built-in types such as tuple and int do not support weak references even when subclassed (This is an implementation detail and may be different across various Python implementations.). This isn't expressive enough to explain: Why some built-in types don't support weak references? What are exactly those types that support weak

Why is this loop faster than a dictionary comprehension for creating a dictionary?

↘锁芯ラ 提交于 2019-12-03 09:21:06
I don't come from a software/computer science background but I love to code in Python and can generally understand why things are faster. I am really curious to know why this for loop runs faster than the dictionary comprehension. Any insights? Problem : Given a dictionary a with these keys and values, return a dictionary with the values as keys and the keys as values. (challenge: do this in one line) and the code a = {'a':'hi','b':'hey','c':'yo'} b = {} for i,j in a.items(): b[j]=i %% timeit 932 ns ± 37.2 ns per loop b = {v: k for k, v in a.items()} %% timeit 1.08 µs ± 16.4 ns per loop You

Why is repr(int) faster than str(int)?

自闭症网瘾萝莉.ら 提交于 2019-12-03 08:12:53
问题 I am wondering why repr(int) is faster than str(int) . With the following code snippet: ROUNDS = 10000 def concat_strings_str(): return ''.join(map(str, range(ROUNDS))) def concat_strings_repr(): return ''.join(map(repr, range(ROUNDS))) %timeit concat_strings_str() %timeit concat_strings_repr() I get these timings (python 3.5.2, but very similar results with 2.7.12): 1.9 ms ± 17.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 1.38 ms ± 9.07 µs per loop (mean ± std. dev. of 7 runs,

Can __setattr__() can be defined in a class with __slots__?

纵然是瞬间 提交于 2019-12-03 08:12:48
Say I have a class which defines __slots__ : class Foo(object): __slots__ = ['x'] def __init__(self, x=1): self.x = x # will the following work? def __setattr__(self, key, value): if key == 'x': object.__setattr__(self, name, -value) # Haha - let's set to minus x Can I define __setattr__() for it? Since Foo has no __dict__ , what will it update? All your code does, apart from negate the value, is call the parent class __setattr__ , which is exactly what would happen without your __setattr__ method. So the short answer is: Sure you can define a __setattr__ . What you cannot do is redefine _

Set literal gives different result from set function call

心已入冬 提交于 2019-12-03 06:28:07
问题 Why does the set function call wipe out the dupes, but parsing a set literal does not? >>> x = Decimal('0') >>> y = complex(0,0) >>> set([0, x, y]) {0} >>> {0, x, y} {Decimal('0'), 0j} (Python 2.7.12. Possibly same root cause as for this similar question) 回答1: Sets test for equality, and until there are new Python releases, the order in which they do this can differ based on the form you hand the values to the set being constructed, as I'll show below. Since 0 == x is true and 0 == y is true,

python 2 vs python 3 performance of random, particularly `random.sample` and `random.shuffle`

*爱你&永不变心* 提交于 2019-12-03 05:59:35
The issue of the performance of the python random module, and in particular, random.sample and random.shuffle came up in this question . On my computer, I get the following results: > python -m timeit -s 'import random' 'random.randint(0,1000)' 1000000 loops, best of 3: 1.07 usec per loop > python3 -m timeit -s 'import random' 'random.randint(0,1000)' 1000000 loops, best of 3: 1.3 usec per loop That's more than a 20% degradation of performance in python3 vs python2. It gets much worse. > python -m timeit -s 'import random' 'random.shuffle(list(range(10)))' 100000 loops, best of 3: 3.85 usec