python - 用未知键初始化一个大字典?还有比这更好的方法吗?

标签 python performance dictionary

所以我有一个包含大约 75000 个元组的列表,我想将它们放入字典中。似乎在大约 20,000 个条目之后,整个程序变慢了,我认为这是因为 dict 在填充时正在动态调整大小。

用于 dict 的键值在元组中的不同位置取决于数据,所以我不能只是将元组列表中的键提取到列表 x 中并调用 d.fromkeys(x) 来预-初始化大字典。我试过组合一个解决方案,但在 ast.literal_eval 评估字典后,我得到的只是一个 {'None': 'None'} :/

我的解决方案(不起作用)。

    d_frame = '{'+('\'None\': \'None\',' * 100000)+'}'
    d = ast.literal_eval(d_frame)

是否有类似这样的内置方法......

谢谢,

编辑:我意识到我的想法很愚蠢。显然你不能在字典中有相同的键....:/

澄清一下,我有一个包含如下数据的元组列表:

 (assembly,strand,start_pos,end_pos,read_count)
 key_format : assembly_strand_val ( where val = start_pos or end_pos depending on other factors )

因为在评估每个元组之前我不知道 key ,所以我无法使用已知 key 初始化字典所以只是想知道我是否可以创建一个空字典然后添加到它..它不会评估每个元组只是为了构建一个列表,然后创建一个字典,然后重复元组评估...

编辑:我意识到瓶颈在哪里。对于每个元组,我都在检查相关键是否已经存在于字典中,但我正在使用;

if key not in dict.keys():
    dict[key] = foo

我没有意识到这每次都会构建一个 key 列表并且可以用更经济的方式替换

if key not in dict:
   dict[key] = foo

改变这个导致速度惊人地提高....

最佳答案

So I have a list of around 75000 tuples that I want to push into a dict.

只需在列表中调用dict。像这样:

>>> list_o_tuples = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
>>> d = dict(list_o_tuples)
>>> d
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}

The key value used for the dict is in a different position in the tuple depending on the data

您向我们展示的代码根本没有证明这一点,但如果您可以编写一个表达式或函数来提取 key ,则可以在字典理解中使用它,或者在生成器表达式中使用它,您可以通过到 dict 函数。

例如,假设元组的第一个元素是实际键元素的索引。然后你会这样写:

d = {tup[tup[0]]: tup for tup in list_o_tuples}

It seems like after around 20,000 entries, the whole program slows down and I assume this is because the dict is being dynamically resized as it is filled.

这似乎不太可能。是的,dict 被调整了大小,但它是按指数方式调整的,而且在超过 20000 的大小时它仍然非常快。分析您的程序以查看它实际上在哪里变慢。我的猜测是您正在做一些二次工作来创建或提取值,或者您正在生成大量存储并导致交换,这两者都与将值插入字典没有任何关系。

无论如何,如果你真的想“预填”字典,你总是可以这样做:

d = dict.from_keys(range(100000))
for i, tup in enumerate(list_o_tuples):
    del d[i]
    d[list_o_tuples[0]] = list_o_tuples[1]

然后字典永远不必调整大小。 (很明显,如果您的键与 0-99999 之间的整数重叠,您将需要使用不同的填充键,但同样的想法也行得通。)

但我敢打赌,这对您的表现绝对没有影响。


I've tried put together a solution, but after the dict is evaluated by ast.literal_eval, all I get is a single {'None': 'None'}

那是因为您正在创建一个具有相同键的 100K 个副本的字典。字典中不能有重复的键,所以当然你最终只会得到一个项目。

然而,这是一个转移注意力的问题。创建一个字符串来评估几乎永远不是答案。你的一大堆代码实际上只是一个更慢、内存效率更低、更难阅读的版本:

d = {'None': 'None' for _ in range(100000)}

或者,如果您愿意:

d = dict([('None', 'None')] * 100000)

关于python - 用未知键初始化一个大字典?还有比这更好的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25656238/

相关文章:

python - 字典如何在python中添加键?

mysql - MySQL 性能的表主键

python - 创建包含前 100 个素数的列表时出现无尽错误

python - os.path.getsize 报告最后带有 L 的文件大小,为什么?

c++ - 在字典中查找单词模式,高性能

python - Django XML 无法加载外部实体

python - 一种将 "pipe"gnu screen 输出到正在运行的 python 进程的方法?

python - 如何获取列表中列表中的两个值?

使用 order by 时 MySQL 查询运行速度非常慢

python - 如何使用 python 解析 nestead json 并从 dict 值构造关系数据库列