小编Kel*_*ndy的帖子

为什么 min 和 max 列为序列操作?

Python 的文档中有一个表,其中包含“大多数序列类型都支持”的“通用序列操作”。例如x in s,它列出了s[i], 和len(s),序列可以通过方法支持这些__contains__,__getitem____len__。但它也列出了min(s)and max(s),我不明白为什么。这两个工作在任何可迭代对象上,我看不出它们在序列方面有什么特别之处。有没有__min____max__或任何其他方式来真正支持他们,有哪几种?如果有的话,我希望立即max(range(10**8))给我结果,而不是花几秒钟。就像那样。如果和10**20 in range(10**30)minmax只是为了展示内置函数,我宁愿希望reversed被列出,因为这确实与序列有关(它适用于每个序列,但不适用于每个可迭代对象)。

所以我忽略了什么吗?还是没__min____max__或其他方式来真正支持min,并max在以前的Python版本的存在,并没有更新的表?或者是否有其他充分的理由将它们列在那里?我糊涂了。

该部分的第一段甚至说:

collections.abc.Sequence美国广播公司提供,使其更容易正确地执行自定义序列类型这些操作。

这听起来像人们期望编写自定义序列类型的人以某种方式实现它们。除非有实际的方法来实现它们,否则这对我来说毫无意义。

python

7
推荐指数
0
解决办法
132
查看次数

Python这里不重用内存吗?Tracemalloc 的输出是什么意思?

我创建了一个包含一百万个对象的列表int,然后用其负值替换每个对象。tracemalloc报告 28 MB 额外内存(每个新int对象 28 字节)。为什么?intPython 不会为新对象重用垃圾收集对象的内存吗?或者我误解了tracemalloc结果?为什么会提到这些数字,它们的真正含义是什么?

\n
import tracemalloc\n\nxs = list(range(10**6))\ntracemalloc.start()\nfor i, x in enumerate(xs):\n    xs[i] = -x\nprint(tracemalloc.get_traced_memory())\n
Run Code Online (Sandbox Code Playgroud)\n

输出(在线尝试!):

\n
(27999860, 27999972)\n
Run Code Online (Sandbox Code Playgroud)\n

如果我替换xs[i] = -xx = -x(因此新对象而不是原始对象被垃圾收集),则输出仅仅是(56, 196)尝试一下)。我保留/丢失这两个物品中的哪一个有什么区别?

\n

如果我循环两次,它仍然只报告(27992860, 27999972)尝试一下)。为什么不是 56MB?第二次运行与第一次运行有何不同?

\n

python memory cpython python-internals tracemalloc

6
推荐指数
1
解决办法
786
查看次数

mylist.reverse() 和 list.reverse(mylist) 是如何执行的?

大概两者mylist.reverse()list.reverse(mylist)最终reverse_slicelistobject.cvialist_reverse_impl或 中执行PyList_Reverse。但他们实际上是如何到达那里的?从 Python 表达式到该 C 文件中的 C 代码的路径是什么?是什么将它们联系起来?它们经历了这两个反向函数中的哪一个(如果有的话)?

赏金更新:Dimitris 的回答(更新 2:我的意思是原始版本,现在扩展之前)及其下面的评论解释了部分内容,但我仍然缺少一些东西,希望看到一个全面的答案。

  • 来自两个 Python 表达式的两条路径如何收敛?如果我理解正确,反汇编和讨论字节码以及堆栈会发生什么,特别是LOAD_METHOD,将澄清这一点。(正如 Dimitris 回答下的评论所做的那样。)
  • 什么是压入堆栈的“未绑定方法”?它是“C 函数”(哪个?)还是“Python 对象”?
  • 我怎么知道它list_reverselistobject.c.h文件中的函数?我不认为 Python 解释器就像“让我们寻找一个听起来相似的文件和一个听起来相似的函数”。我宁愿怀疑该list类型是在某处定义的,并且以某种方式在名称“”下“注册” list,并且该reverse函数在名称“ reverse”下“注册”(也许这就是LIST_REVERSE_METHODDEF宏的作用?)。
  • 我对(对于这个问题)堆栈帧、参数处理和类似的东西不感兴趣(所以可能里面 发生的事情不多call_function)。真正让我感兴趣的是我最初所说的,从 Python 表达式到该 C 文件中的 C 代码的路径。最好是如何找到这样的路径。

解释我的动机:对于另一个问题,我想知道当我调用list.reverse(mylist). 我相当有信心通过浏览和搜索名称找到了它。但我想更加确定,并且更好地理解这些联系。

python cpython python-internals

5
推荐指数
1
解决办法
378
查看次数

用 O(1) 空间逐行读取数字

许多编码挑战在同一行中有多个数字,通常第一行告诉多数字行中有多少个数字:

4
31 415 9 26
Run Code Online (Sandbox Code Playgroud)

通常我只是读取整行,然后.split()将字符串映射到数字。

但是有没有一种好方法可以一次读取整行,而是一次读取一个数字呢?为了节省内存,要么因为我不能或不想整行读入内存。我只想使用 O(1) 空间(假设数字很小/有界,所以它们的大小是 O(1) )。不必绝对最小,例如,如果解决方案在内部一次读取完整的 4 KB 内存页,那没关系,仍然是 O(1) 并且相对较小。对于用例,请考虑一行上有数百万个数字,并且内存限制比方说低于 1 MB。

在 C++ 中我会这样做:

4
31 415 9 26
Run Code Online (Sandbox Code Playgroud)

我编写了这个生成器,它接受一个文件对象并为我提供一个字符串迭代器。对于上面的示例,它生成字符串'4''31''415''9''26'它一次读取一个字符,并按照以下确定的空格字符进行分割.isspace()

def split(file):
    value = []
    while char := file.read(1):
        if char.isspace():
            if value:
                yield ''.join(value)
            value.clear()
        else:
            value.append(char)
    if value:
        yield ''.join(value)
Run Code Online (Sandbox Code Playgroud)

但这当然是极其复杂和缓慢的,我什至不知道这种str.isspace用法是否等同于str.split空白。它只是说明了实现我想要的目标的一种方法。

编辑:这是一种更简单的方法,但仍然比我想要的更复杂和缓慢。我正在寻找一些内置的方法,以 …

python memory space-complexity

5
推荐指数
0
解决办法
201
查看次数

在 python 中列出 __sizeof__() 结果

我以 3 种不同的方式创建列表,并且该__sizeof__()方法为每种方式返回不同的值:

>>> l1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(l1.__sizeof__())
120
>>> l2 = list(i for i in range(10))
>>> print(l2.__sizeof__())
136
>>> l3 = [i for i in range(10)]
>>> print(l3.__sizeof__())
168
Run Code Online (Sandbox Code Playgroud)

创建方式是否影响尺寸计算?我的假设是,数据结构应该相同。

对元组的类似测试返回相同的大小值:

>>> t1 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> print(t1.__sizeof__())
104
>>>
>>> t2 = tuple(i for i in range(10))
>>> print(t2.__sizeof__())
104
Run Code Online (Sandbox Code Playgroud)

python tuples list

5
推荐指数
0
解决办法
41
查看次数

如何优化这个异或和算法?

我正在尝试解决这个 hackerrank 问题https://www.hackerrank.com/challenges/xor-subsequence/problem

\n
from functools import reduce\n\ndef xor_sum(arr):\n    return reduce(lambda x,y: x^y, arr)    \n\ndef xorSubsequence(arr):\n    freq = {}\n    max_c = float("-inf") # init val\n    min_n = float("inf") # init val\n    \n    for slice_size in range(1, len(arr)+1):\n        for step in range(0, len(arr)+1-slice_size):\n            n = xor_sum(arr[i] for i in range(step,step+slice_size))\n            \n            freq[n] = freq.get(n,0)+1\n            if freq[n] >= max_c and (n < min_n or freq[n]> max_c):\n                min_n = n\n                max_c = freq[n]\n\n    return  min_n, freq[min_n]\n
Run Code Online (Sandbox Code Playgroud)\n

但它超时了,因为它是 ~O(n^3)。\n我觉得有一些数学技巧,有人可以向我解释解决方案吗?我尝试阅读讨论中的一些解决方案,但我不太明白。

\n

问题副本:

\n …

python algorithm math xor time-complexity

5
推荐指数
2
解决办法
1144
查看次数

从盒子中取出物品的方法数

我遇到了以下算法问题,该问题对运行时间有严格的限制(<10s并且没有大的内存占用),我被难住了。我的方法一半的测试用例都失败了。

问题

一个盒子包含许多物品,一次只能取出 1 个或 3 个。

盒子可以有多少种方式被清空?答案可能非常大,因此将其返回为 10^9+7 的模。

例如,最初有n=7个项目。可以通过九种方式删除它们,如下所示:

1.(1,1,1,1,1,1,1)
2.(1.1.1.1.3)
3.(1,1,1,3,1)
4.(1,1,3,1,1)
5.(1,3,1,1,1)
6.(3,1,1,1,1)
7.(1,3,3)
8.(3,1,3)
9.(3,3,1)
Run Code Online (Sandbox Code Playgroud)

所以该函数应该返回 9。

函数描述:您的函数必须接受一个参数,n表示项目的数量,并返回一个整数,表示清空盒子的方式数。

限制条件:1<=n<=10^8

案例示例:

Input: 1
Sample OutPut: 1
Explanation: There is only 1 way to remove 1 item. Answer=(1%1000000007)=1

Input: 7
Sample OutPut: 9
There is only 9 ways to remove 7 items
Run Code Online (Sandbox Code Playgroud)

我的方法

这导致了一个标准的递归关系,其中f(n) = f(n-3) + f(n-1)n > 2,所以我这样做如下

def memoized_number_of_ways(dic, n):
    if n not in dic:
        dic[n] = memoized_number_of_ways(dic, n-3) …
Run Code Online (Sandbox Code Playgroud)

algorithm dynamic-programming combinatorics

4
推荐指数
1
解决办法
211
查看次数

使用复数来存储图形坐标有什么好处?

我正在寻找一个将坐标存储为复数的 Advent of Code 谜题的解决方案:

 heightmap = {
    complex(x, y): c
        for y, ln in enumerate(sys.stdin.read().strip().split("\n"))
        for x, c in enumerate(ln)
}
Run Code Online (Sandbox Code Playgroud)

然后稍后访问它们,如下所示:

for xy, c in heightmap.items():
    for d in (1, -1, 1j, -1j):
        if ord(heightmap.get(xy + d, "{")) <= ord(c) + 1:
            G.add_edge(xy, xy + d)
Run Code Online (Sandbox Code Playgroud)

我可以看到这段代码使“获取邻居”行易于编写/思考,但我不认为值得增加复杂性(没有双关语)。

有人可以解释为什么将网格坐标存储为复数很有用吗?

python graph-theory complex-numbers

4
推荐指数
1
解决办法
203
查看次数

为什么 set.remove 这里这么慢?

(摘自另一个问题。)像这样逐个删除该集合的 200,000 个元素需要 30 秒(在线尝试!):

s = set(range(200000))
while s:
    for x in s:
        s.remove(x)
        break
Run Code Online (Sandbox Code Playgroud)

为什么这么慢?删除集合元素应该很快。

python performance set python-internals

4
推荐指数
1
解决办法
203
查看次数

线性时间内所有子数组的最大值之和乘以它们的长度

给定一个数组,我应该在线性时间内计算以下总和:

我最幼稚的实现是 O(n 3 ):

sum_ = 0

for i in range(n):
    for j in range(n, i, -1):
        sum_ += max(arr[i:j]) * (j-i)
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么做。我尝试过很多算法,但它们最多是 O(n*log(n)),但我应该在线性时间内解决它。另外,我不明白,是否有一种数学方法可以只查看数组并告诉上面总和的结果?

python arrays algorithm math time-complexity

3
推荐指数
1
解决办法
279
查看次数