python - 更快的 Python 技术,用于从相互为多个的数字列表中计算三元组
问题描述
假设我们有一个数字列表,l
。我需要从 COUNT 长度为 3 的所有元组l
,(l_i,l_j,l_k)
以便l_i
均分l_j
和l_j
均分l_k
。规定指标i,j,k
有关系i<j<k
IE;
如果l=[1,2,3,4,5,6]
,那么元组将是[1,2,6], [1,3,6],[1,2,4]
,所以COUNT
将是 3。
如果l=[1,1,1]
,那么唯一的元组是[1,1,1]
,所以COUNT
是 1。
这是我到目前为止所做的,使用列表推导:
def myCOUNT(l):
newlist=[[x,y,z] for x in l for y in l for z in l if (z%y==0 and y%x==0 and l.index(x)<l.index(y) and l.index(y)<l.index(z))]
return len(newlist)
>>>l=[1,2,3,4,5,6]
>>>myCOUNT(l)
3
这是可行的,但是随着l
时间的推移(它可以长达 2000 个元素),所花费的时间会增加太多。有没有更快/更好的方法来做到这一点?
解决方案
We can count the number of triples with a given number in the middle by counting how many factors of that number are to its left, counting how many multiples of that number are to its right, and multiplying. Doing this for any given middle element is O(n) for a length-n list, and doing it for all n possible middle elements is O(n^2).
def num_triples(l):
total = 0
for mid_i, mid in enumerate(l):
num_left = sum(1 for x in l[:mid_i] if mid % x == 0)
num_right = sum(1 for x in l[mid_i+1:] if x % mid == 0)
total += num_left * num_right
return total
Incidentally, the code in your question doesn't actually work. It's fallen into the common newbie trap of calling index
instead of using enumerate
to get iteration indices. More than just being inefficient, this is actually wrong when the input has duplicate elements, causing your myCOUNT
to return 0 instead of 1 on the [1, 1, 1]
example input.
推荐阅读
- android - RecyclerView 在日志中显示 Null 值但没有错误
- python - 使用 Sequential API 从 Keras 自动编码器中提取编码/解码模型
- python-3.x - IBM 树莓派物联网服务
- powerapps - 如何在 Powerapps 中同时使用 collect 和 if 函数?
- r - 每隔一行拆分变量以在 data.frame 中形成两个新列
- android - 根据屏幕Android Studio在GridLayout中设置按钮的宽度和高度
- python - 如何强制 Python 导航到网页并打印所有锚点(a-html)
- java - 将 3 个链表合并为 1 个(Java)
- javascript - 如何在加载网页时隐藏 div
- ms-access - 标准中的 OnlyDigits 函数