Python-为每个给定密钥文件创建字典
我正在研究一个文本解析算法(开源端项目)。我非常感谢你的建议 我有一个以制表符分隔的txt文件,它按第一列(下面的示例数据集)排序。此列中存在重复条目。 最后,我想使用散列来指向所有具有相同键(第一列值)的值。如果出现一个新的密钥,哈希的内容将被序列化、保存等,然后清除,以便新的密钥填充它。因此,我的目标是只有一把钥匙在场。因此,如果我有N个唯一的键,我希望将N个散列分别指向它们各自的条目。尽管数据集的大小和内存堆都是GBs,但不会有多大帮助,因此我的推理是为每个键创建一个哈希,并分别处理每个键 样本数据集 A.23.4421 A-23.442 A.76.2224 B32.1232 B-23.001 C652.123 ... 因此,在上面的数据集片段中,我希望有一个“a”的散列(指向其各自的3倍项)。读取“B”时,序列化“A”哈希并清除哈希内容。对“B”重复此操作,直到数据集结束 我的伪代码如下: declare hash for item in the dataset: key, value = item[0], item[1:] if key not in hash: if hash.size is 0: // pertains to the very first item hash.put(key, value) else: clear hash // if a new key is read but a diff. key is present. else: hash.put(key, value) // key already there so append it. 声明散列 对于数据集中的项: 键,值=项[0],项[1:] 如果密钥不在哈希中: 如果hash.size为0://则与第一项相关 hash.put(键、值) 其他: 清除哈希//如果读取了新密钥但存在差异密钥。 其他: hash.put(key,value)//key已经存在,所以要追加它。 如果有任何关于如何有效实现上述算法的建议,我将不胜感激。此外,如果我的散列推理/方法没有效率,或者可以提出改进,我将非常感谢。我的目标是最终创建内存散列,直到出现一个新的键 谢谢, p、 您可以为第一列中的每个键打开anydbm(2.x)或dbm(3.x),以列的值命名。这是相当琐碎的——我不确定问题是什么 您还可以使用类似于我的cachedb模块的东西,让它判断某个东西是否是“新的”:我在两个项目中使用过它,都取得了很好的效果Python-为每个给定密钥文件创建字典,python,file,dictionary,Python,File,Dictionary,我正在研究一个文本解析算法(开源端项目)。我非常感谢你的建议 我有一个以制表符分隔的txt文件,它按第一列(下面的示例数据集)排序。此列中存在重复条目。 最后,我想使用散列来指向所有具有相同键(第一列值)的值。如果出现一个新的密钥,哈希的内容将被序列化、保存等,然后清除,以便新的密钥填充它。因此,我的目标是只有一把钥匙在场。因此,如果我有N个唯一的键,我希望将N个散列分别指向它们各自的条目。尽管数据集的大小和内存堆都是GBs,但不会有多大帮助,因此我的推理是为每个键创建一个哈希,并分别处理每个键
无论采用哪种方式,您都可能会将键设置为由换行符或空值或其他内容分隔的ascii浮点列表。您不会明确说明您提供的排序数据是否是典型的,或者同一个键是否可以在整个文件中与其他键交错,这确实会对算法产生根本性的影响。我从您的示例代码推断,它们将以任意顺序出现 你也没有说你打算把这样提取的数据放在哪里。这可能非常重要—有许多不同的方法来存储数据,应用程序可能是确定访问时间的关键功能。因此,您可能需要考虑各种不同存储类型的使用。在不知道您打算如何使用结果结构的情况下,以下建议可能不合适
因为数据是浮点数字,所以您可能需要考虑使用以保持简单的浮点数的列表,这些浮点数是针对字母表的。这样做的优点是,所有进出外部存储器的酸洗和解酸洗都是自动处理的。如果需要增加速度,请考虑使用更有效的酸洗协议(未使用的参数之一为代码> Selv.On()/<代码>。 您可能想知道为什么我不在已经看到密钥的情况下使用
shelf[k].append(v)
。这是因为只有键分配的操作才会触发值更改的检测。您可以阅读shelve模块文档以了解更多详细信息,并了解如何使用二进制pickle格式
还请注意,由于
shelve.open()
的“c”参数,此程序每次运行时都会重新创建shelf,请使用itertools.groupby,将文件作为迭代器传递给它:
from itertools import groupby
from cStringIO import StringIO
sourcedata = StringIO("""\
A ... 23.4421
A ... -23.442
A ... 76.2224
B ... 32.1232
B ... -23.001
C ... 652.123""")
# or sourcedata = open("zillion_gigabyte_file.dat")
for key,lines in groupby(sourcedata, key=lambda s:s.split()[0]):
accum = [float(s.split()[2]) for s in lines]
print key, accum
groupby非常聪明和高效,一次只在内存中保存很少的数据,直到最后一刻才以迭代器的形式保存内容。在groupby中,您描述的是散列,一次只在内存中保留一个,所有这些都已经为您完成了。不清楚您的问题是什么。看起来您只是想将具有相同键的值分组在一起。由于键已经被排序,一个列表就足够了,不需要散列。
# Transform the data:
# note it's actually more efficient to process line-by-line
# as you read it from a file - obviously it's best to try
# to avoid reading the whole data set into memory at once.
data = """\
A ... 23.4421
A ... -23.442
A ... 76.2224
B ... 32.1232
B ... -23.001
C ... 652.123"""
data = [(k, float(v))
for (k, _, v) in
[_.split() for _ in data.splitlines()]]
# create a shelve
import shelve
shelf = shelve.open("myshelf", "c")
# process data
for (k, v) in data:
if k in shelf:
# see note below for rationale
tmp = shelf[k]
tmp.append(v)
shelf[k] = tmp
else:
shelf[k] = [v]
# verify results
for k in shelf.keys():
print k, shelf[k]
from itertools import groupby
from cStringIO import StringIO
sourcedata = StringIO("""\
A ... 23.4421
A ... -23.442
A ... 76.2224
B ... 32.1232
B ... -23.001
C ... 652.123""")
# or sourcedata = open("zillion_gigabyte_file.dat")
for key,lines in groupby(sourcedata, key=lambda s:s.split()[0]):
accum = [float(s.split()[2]) for s in lines]
print key, accum