为什么False值(0)的字节数小于True(1)? - python

我在研究sysgetsizeof()时发现False(或0)比True(或1)包含更少的字节。这是为什么?

import sys

print("Zero: " + str(sys.getsizeof(0)))
print("One: " + str(sys.getsizeof(1)))
print("False: " + str(sys.getsizeof(False)))
print("True: " + str(sys.getsizeof(True)))

# Prints:
# Zero: 24
# One: 28
# False: 24
# True: 28

实际上,其他数字(也包括不止一个数字的数字)是28个字节。

for n in range(0, 12):
  print(str(n) + ": " + str(sys.getsizeof(n)))

# Prints:
# 0: 24
# 1: 28
# 2: 28
# 3: 28
# 4: 28
# 5: 28
# 6: 28
# 7: 28
# 8: 28
# 9: 28
# 10: 28
# 11: 28

甚至更多:sys.getsizeof(999999999)也是28个字节! sys.getsizeof(9999999999)是32。

发生什么了?我假设布尔TrueFalse在内部分别转换为01,但是为什么大小与其他较低的整数零不同?

附带的问题:这是特定于Python(3)表示这些项目的方式,还是通常在操作系统中如何显示数字?

参考方案

请记住,Python int值的大小是任意的。这是如何运作的?

好吧,在CPython1中,一个int由PyLong_Object表示,它具有4字节大块的数组2,每个大块包含30个bit3的数字。

  • 0完全不占用任何块。
  • 1-(1<<30)-1占用1个块。
  • 1<<30-(1<<60)-1需要2个块。
  • 等等。

    这有点过分简化了;有关完整的详细信息,请参见源代码中的 longintrepr.h

    在Python 2中,有两种不同的类型,分别称为intlongint由直接嵌入标头中的C 32位带符号整数4表示,而不是块数组。 long就像Python 3 int一样。

    如果您对0L1L等进行相同的测试以明确要求long值,您将获得与Python 3相同的结果。但是如果没有L后缀,则任何32位的文字都将为您提供int,并且只有太大的文字才能为您提供long s.5(这意味着(1<<31)-1int,但是1<<31是2块long。)

    1.在另一种实现中,可能并非如此。在IIRC中,Jython的功能与CPython大致相同,但是IronPython使用C#“bignum”实现。

    2.为什么用30位而不是32位?主要是因为pow**的实现可以更简单,更快速,如果可以假设10可以将两个“数字”中的位数划分为零。

    3.它使用C "struct hack"。从技术上讲,Py_LongObject是28个字节,但是没有人分配Py_LongObject;他们malloc 24、28、32、36等字节,然后转换为Py_LongObject *

    4.实际上,Python int是C long,只是使事情变得混乱。因此,C API充满了诸如PyInt_FromLong(其中long表示“32位整数”)和PyLong_FromSize_t(其中long表示“bignum”)之类的东西。

    5.早期版本的Python 2.x并没有很好地集成intlong,但是希望没有人再担心这些。

    在Django中聚合save()? - python

    我正在使用带有sqlite后端的Django,并且写入性能是一个问题。在某个阶段,我可能会毕业于“适当的”数据库,但是目前我仍然坚持使用sqlite。我认为我的写入性能问题可能与以下事实有关:我创建了大量行,并且大概每次save()一个行时,它都会锁定,解锁和同步磁盘上的数据库。如何将大量save()调用聚合到一个数据库操作中? 参考方案 编辑:不建议使用c…

    如何在Linux上安装2个Anacondas(Python 2.7和3.5)? - python

    我想使用Python 2和3版本。我已经读过有关conda环境的用法,但是不断向终端source (de)activate py27写入内容似乎不方便。如picture所示,如何使用命令选择内核版本? 参考方案 您在该图像中寻找的是Jupyter Notebook。您需要使用Jupyter和所需的python版本创建环境:conda create -n py…

    为什么在for循环中将单词从复数形式转换为单数形式会花费这么长时间(Python 3)? - python

    这是我的代码,用于从CSV文件读取文本并将一列中的所有单词从复数形式转换为单数形式:import pandas as pd from textblob import TextBlob as tb data = pd.read_csv(r'path\to\data.csv') for i in range(len(data)): blob …

    为什么主要的可运行Python脚本未编译为pyc文件(如模块)? - python

    我了解,当您导入模块时,该文件会被编译成.pyc文件以使其更快?为什么主文件也未编译为.pyc?这会减慢速度吗?那么将主文件保持得尽可能小会更好,还是没关系? 参考方案 加载模块时,会将py文件“字节编译”为pyc文件。时间戳记录在pyc文件中。 这样做不是为了使其运行更快,而是使其加载更快。 因此,在加载模块时使用“字节编译”模块是有意义的。 http:/…

    如何在“后台”中运行脚本的一部分(单个函数)? - python

    我在具有以下基本结构(伪代码)的服务器上运行python脚本:for data_item in data_items: processed_result=process_data(data_item); #this takes time T0 upload_result_to_site(processed_result) #this takes time T…