In [55]: a = 5
In [56]: b = 6
In [57]: (a, b) = (b, a)
In [58]: a
Out[58]: 6
In [59]: b
Out[59]: 5
Run Code Online (Sandbox Code Playgroud)
如何交换a和b的值在内部工作?它肯定不使用临时变量.
为什么CPython(没有关于其他Python实现的线索)有以下行为?
tuple1 = ()
tuple2 = ()
dict1 = {}
dict2 = {}
list1 = []
list2 = []
# makes sense, tuples are immutable
assert(id(tuple1) == id(tuple2))
# also makes sense dicts are mutable
assert(id(dict1) != id(dict2))
# lists are mutable too
assert(id(list1) != id(list2))
assert(id(()) == id(()))
# why no assertion error on this?
assert(id({}) == id({}))
# or this?
assert(id([]) == id([]))
Run Code Online (Sandbox Code Playgroud)
我有一些想法可能,但找不到具体原因.
编辑
进一步证明格伦和托马斯的观点:
[1] id([])
4330909912
[2] x = []
[3] …Run Code Online (Sandbox Code Playgroud) 受这个关于缓存小整数和字符串的问题的启发,我发现了以下我不理解的行为.
>>> 1000 is 10**3
False
Run Code Online (Sandbox Code Playgroud)
我以为我理解了这种行为:1000是很大的缓存.1000和10**3指向2个不同的对象.但我错了:
>>> 1000 is 1000
True
Run Code Online (Sandbox Code Playgroud)
因此,Python可能会将计算与"正常"整数区别对待.但这种假设也是不正确的:
>>> 1 is 1**2
True
Run Code Online (Sandbox Code Playgroud)
如何解释这种行为?
当通过解包参数调用函数时,它似乎会增加两次递归深度.我想知道为什么会这样.
一般:
depth = 0
def f():
global depth
depth += 1
f()
try:
f()
except RuntimeError:
print(depth)
#>>> 999
Run Code Online (Sandbox Code Playgroud)
通过拆包电话:
depth = 0
def f():
global depth
depth += 1
f(*())
try:
f()
except RuntimeError:
print(depth)
#>>> 500
Run Code Online (Sandbox Code Playgroud)
理论上两者都应达到1000左右:
import sys
sys.getrecursionlimit()
#>>> 1000
Run Code Online (Sandbox Code Playgroud)
这发生在CPython 2.7和CPython 3.3上.
在PyPy 2.7和PyPy 3.3上存在差异,但它要小得多(1480 vs 1395和1526 vs 1395).
从反汇编中可以看出,除了调用类型(CALL_FUNCTIONvs CALL_FUNCTION_VAR)之外,两者之间几乎没有区别:
import dis
Run Code Online (Sandbox Code Playgroud)
def f():
f()
dis.dis(f)
#>>> 34 0 LOAD_GLOBAL 0 (f)
#>>> 3 CALL_FUNCTION 0 (0 positional, …Run Code Online (Sandbox Code Playgroud) 我需要一种更快的方式来存储和访问大约3GB的k:v对.其中k是string或integer并且v是一个np.array(),可以是不同的形状.有没有任何对象,比标准python dict在存储和访问这样的表时更快?例如,a pandas.DataFrame?
到目前为止,我已经了解python dict是一个相当快速的哈希表实现,有什么比我的具体案例更好的?
您好我正在尝试理解Python的引用如何通过工作.我有一个例子:
>>>a = 1
>>>b = 1
>>>id(a);id(b)
140522779858088
140522779858088
Run Code Online (Sandbox Code Playgroud)
这非常有意义,因为a和b都引用了与身份相同的值.我不太明白的是这个例子:
>>>a = 4.4
>>>b = 1.0+3.4
>>>id(a);id(b)
140522778796184
140522778796136
Run Code Online (Sandbox Code Playgroud)
与此示例不同:
>>>a = 2
>>>b = 2 + 0
>>>id(a);id(b)
140522779858064
140522779858064
Run Code Online (Sandbox Code Playgroud)
是因为在第3个例子中,0 int对象被解释器视为"None",并且没有被识别为需要与变量"a"引用的对象不同的身份(2)?而在第二个例子中,"b"是添加两个不同的int对象,而解释器是为要添加的两个对象分配内存,这给变量"a",与变量"b"不同的标识?
我有一个pandas.Series包含整数,但我需要将这些转换为字符串以用于某些下游工具.所以假设我有一个Series对象:
import numpy as np
import pandas as pd
x = pd.Series(np.random.randint(0, 100, 1000000))
Run Code Online (Sandbox Code Playgroud)
在StackOverflow和其他网站上,我见过大多数人认为最好的方法是:
%% timeit
x = x.astype(str)
Run Code Online (Sandbox Code Playgroud)
这大约需要2秒钟.
使用时x = x.apply(str),只需0.2秒.
为什么x.astype(str)这么慢?应该推荐的方式x.apply(str)吗?
我主要对python 3的行为感兴趣.
我对"内置"功能一词感到困惑.我认为这只意味着内置于解释器中的那些函数并记录在其中 -
2.内置函数
但似乎标准库模块中定义的函数也是内置函数(在某些情况下).例如 -
>>> import os
>>> os.chdir
<built-in function chdir>
>>> import warnings
>>> warnings.warn
<built-in function warn>
>>> import json
>>> json.dumps
<function dumps at 0x7f3643a240d0> # not built-in
>>> dir
<built-in function dir>
>>>
Run Code Online (Sandbox Code Playgroud)
那么什么时候标准库模块中的函数称为内置函数,何时不是?
我理解字典是在Python 3.6+中排序的插入,作为3.6中的实现细节和3.7+中的官方.
鉴于它们是有序的,似乎很奇怪,没有方法可以通过插入顺序检索字典的第i项.该唯一的解决方案可出现有O(ñ)的复杂性,无论是:
list.__getitem__.enumerate循环中的字典项,并在达到所需索引时返回值.同样,O(n)时间复杂度.由于从list具有O(1)复杂度的项目中获取项目,是否有办法通过字典实现相同的复杂性?无论是定期dict还是collections.OrderedDict工作.
如果不可能,是否存在阻止这种方法的结构性原因,或者这只是一个尚未考虑/实施的特征?
如果我们制作这样的病态土豆:
>>> class Potato:
... def __eq__(self, other):
... return False
... def __hash__(self):
... return random.randint(1, 10000)
...
>>> p = Potato()
>>> p == p
False
Run Code Online (Sandbox Code Playgroud)
我们可以通过这种方式打破集合和切换(注意:即使__eq__返回True它也是一样的,它正在破坏它们的哈希):
>>> p in {p}
False
>>> p in {p: 0}
False
Run Code Online (Sandbox Code Playgroud)
此外len({p: 0, p: 0}) == 2,并{p: 0}[p]引发KeyError,基本上所有与映射相关的东西都会出现,如预期的那样.
但我没想到的是我们不能打破名单
>>> p in [p]
True
Run Code Online (Sandbox Code Playgroud)
这是为什么?它似乎是list.__contains__迭代,但它首先在检查相等性之前检查身份.由于不是身份意味着相等的情况(例如参见NaN对象),列表在身份比较中短路的原因是什么?
python ×10
python-internals ×10
python-3.x ×3
cpython ×2
dictionary ×2
identity ×1
literals ×1
numpy ×1
pandas ×1
performance ×1
recursion ×1
reference ×1
semantics ×1
string ×1
tuples ×1