- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个关于搜索相同数字的问题。
我所拥有的:
我有一个带有字典的清单。在此词典中,有2对key-val,一个是唯一的id,另一个是带有数字的列表。
我需要做什么:
如果其他字典中的其他列表中有相同的数字,则需要定义,然后在parent
字典中写入processed_data
id和相同的数字。但是我的all
列表非常大,此过程大约需要3.6天。
所以这是一个问题
我想找到其他任何方法来更快地处理它,如果可能的话,大约要花12个小时,感谢您的帮助。
PS(也许一些多处理或线程处理将以某种方式有所帮助,但我对是否可能存在很大疑问)
(在相同的字典及其列表中查找相同的数字时,我们将省略此处的情况)
# List with dictionaries:
all = [
{'id' : 0, 'numbers' : [1, 2, 3, 4, 5]},
{'id' : 1, 'numbers' : [5, 7, 9]},
{'id' : 2, 'numbers' : [10, 12, 14]},
{'id' : 3, 'numbers' : [3, 12, 5]}
]
# Here I will store the results
processed_data = {}
# For every row
for every in all:
id = every['id']
numbers_list = every['numbers']
for every_2 in all:
numbers_list_2 = every_2['numbers']
# If number exists in the other row
# I remember id of the list wich contain this number
# And number
for number in numbers_list_2:
if number in numbers_list:
processed_data[id] = number
print(processed_data)
{0: 5, 1: 5, 2: 12, 3: 5}
最佳答案
确实,您的列表处理效率非常低下,因为您将每个字典与其他每个字典组合(一个O(N ^ 2)顺序处理),然后通过将长度为K的列表中的每个值与另一个数字列表相组合来复合该列表连续扫描具有类似的长度,因此最终得到O(N ^ 2 * K ^ 2)。这将需要很长时间。这是顺序扫描,因为您对数字(number in numbers_list
)进行的容纳测试必须逐一测试numbers_list
列表中的每个值,直到找到匹配项或列表用尽。
您想了解sets。 Sets让您测试数字是否恒定存在,因为每个值本身都是通过其哈希值指向其在数据结构中位置的键(因此something in setvalue
只需要查看sett表中是否存在hash(something)
)。您还可以非常有效地获得它们的交点,因此两组中都存在一组数字。对于两组平均大小K,这需要O(K)线性时间。交集就是setA & setB
。
我会将您的数据结构转换为包含以开头的集合,然后针对两个列表之间的交集,记录集合中每个数字的和两个 ID,因为这两个列表都有相同的数字。这样一来,您就可以减少O(N ^ 2)配对,因为当您用ID B测试了ID A时,您不必针对ID A对ID B做相同的事情。从技术上讲,这仍然是O(N ^ 2) ),但实际上是triangle number or arithmetic series; N + N-1 + N-2 ....即(N *(N + 1))// 2,对于实际问题,迭代次数要低得多,要比完整的N ^ 2好得多;将方法与实际情况和有限的输入大小进行比较时,将花费的时间减半仍然很重要。
看起来像这样:
all = [
{'id' : 0, 'numbers' : [1, 2, 3, 4, 5]},
{'id' : 1, 'numbers' : [5, 7, 9]},
{'id' : 2, 'numbers' : [10, 12, 14]},
{'id' : 3, 'numbers' : [3, 12, 5]},
]
# conversion to sets
for d in all:
d['numbers'] = set(d['numbers'])
processed_data = {}
for i, entry in enumerate(all):
id1 = entry['id']
for j in range(i + 1, len(all)):
id2 = all[j]['id']
for num in entry['numbers'] & all[j]['numbers']:
processed_data.update({id1: num, id2: num})
itertools.combinations()
为我们进行配对,从而进一步简化嵌套循环:
from itertools import combinations
# everything before the loop the same up to setting `processed_data`
for entry1, entry2 in combinations(all, r=2):
id1, id2 = entry1['id'], entry2['id']
for num in entry1['numbers'] & entry2['numbers']:
processed_data.update({id1: num, id2: num})
id
作为唯一值,但是对于给定的
all
,您在
id
中的输入可能具有多个条目,因此您可以在此处进一步减少N和K,方法是首先将每个
id
值的数字合并为一个单独的集合。您可以通过将
all
映射到以
id
为键并设置为值的字典来实现。因为我们仍然受O(N ^ 2)算法约束以组合
all
中的条目,所以减少N会产生很大影响;如果N = 1000,则转到N = 999会从考虑中删除1000个交集(替换为一个集更新以首先合并重复的id)。
from itertools import combinations
all = [
{'id' : 0, 'numbers' : [1, 2, 3, 4, 5]},
{'id' : 1, 'numbers' : [5, 7, 9]},
{'id' : 2, 'numbers' : [10, 12, 14]},
{'id' : 3, 'numbers' : [3, 12, 5]},
# I've added another entry with id 1, but different numbers
{'id' : 1, 'numbers' : [17, 42, 11]},
]
# conversion to sets
all_sets = {}
for d in all:
all_sets.setdefault(d['id'], set()).update(d['numbers'])
# if memory is an issue at this point, consider adding 'del all'.
processed_data = {}
for (id1, numbers1), (ids2, numbers2) in combinations(all_sets.items(), r=2):
for num in numbers1 & numbers2:
processed_data.update({id1: num, id2: num})
processed_data = {
id: num
for (id1, num1), (ids2, num2) in combinations(all_sets.items(), r=2)
for num in num1 & num2
for id in (id1, id2)
}
id
的另一个列表共享的最后一个数字。如果要记录所有此类数字,则需要制作
processed_data
值列表或集合,以便可以容纳多个数字的容器。
dict.setdefault()
来确保有一个空容器,并将其添加到返回的容器中:
processed_data = {}
for (id1, numbers1), (ids2, numbers2) in combinations(all_sets.items(), r=2):
for num in numbers1 & numbers2:
processed_data.setdefault(id1, set()).add(num)
processed_data.setdefault(id2, set()).add(num)
processed_data.setdefault(id1, []).append(num)
等。对于您的示例
all
数据,将产生:
>>> processed_data
{0: {3, 5}, 3: {3, 5, 12}, 1: {5}, 2: {12}}
numbers
包含可哈希值,即整数。如果您的实际设置没有可散列的值,请通过将其转换为该作业来使其可散列。节省时间是值得的。
all_sets = {}
for d in all:
all_sets.setdefault(d['id'], set()).update(map(tuple, d['numbers']))
map(tuple, d['numbers'])
将
tuple()
应用于每个元素,然后再将这些元组添加到集合中。
关于python - 如何快速用字典识别列表中的重复数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59627410/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!