【问题标题】:Can a python generator work like a dictionary?python生成器可以像字典一样工作吗?
【发布时间】:2017-03-22 15:11:29
【问题描述】:

我在 Excel 电子表格中有一大列公司信息。我需要将公司信息带入我的程序进行处理。

每家公司都有一个独特的标签,用于访问这些公司。我可以使用标签作为键和公司信息作为值来创建字典,例如{label1: company1, label2: company2, ...}。这样做的话,当字典被创建时,它会占用太多的内存。

是否可以创建一个可以像字典一样使用的生成器?

【问题讨论】:

  • @JoshLee:OP 明确声明他希望避免创建字典...
  • 您可以使用__getitem__ 方法创建一个对象,该方法在您调用mydata[...] 时即时查找内容,如果这是您想要的。
  • 您需要定义您实际尝试解决的问题。是基于密钥的快速访问这些数据吗?顺序访问?合并具有相同键的记录?数据有多大?内存限制是什么?“消耗太多内存”是什么意思?
  • 如果您无法将所有键都放入内存中,另一种选择是使用 sqlite db 或快速 pkl 文件。因为您仍然需要在某处查找数据。但是您可以创建一个生成器,它遍历文件并为每一行返回一个小元组。
  • 在内存和速度之间存在不可避免的权衡,字典为您提供(大部分)O(l) 查找但保存在内存中,其他内存效率更高的方法将不那么快速

标签: python dictionary generator


【解决方案1】:

似乎这个问题的主要目标是拥有一个行为像字典的对象,而不在 RAM 中保存字典的内容(OP:“通过这样做,当字典创建后,它会占用太多内存。”)。这里的一种选择是使用 sqlitedict,它模仿 Python 字典 API,并在后台使用 Sqlite 数据库。

这是当前文档中的示例:

>>> # using SqliteDict as context manager works too (RECOMMENDED)
>>> with SqliteDict('./my_db.sqlite') as mydict:  # note no autocommit=True
...     mydict['some_key'] = u"first value"
...     mydict['another_key'] = range(10)
...     mydict.commit()
...     mydict['some_key'] = u"new value"
...     # no explicit commit here
>>> with SqliteDict('./my_db.sqlite') as mydict:  # re-open the same DB
...     print mydict['some_key']  # outputs 'first value', not 'new value'

【讨论】:

    【解决方案2】:

    您可以创建一个覆盖__getitem__ 方法的类。喜欢:

    class Foo:
    
        def __getitem__(self,key):
            # ...
            # process the key
            # for example
            return repr(key)
    

    现在如果你创建一个Foo:

    >>> somefoo = Foo()
    >>> somefoo['bar']
    "'bar'"
    >>> somefoo[3]
    '3'
    

    所以在语法上它“有点”像字典一样工作。

    您还可以将 generatorsend 一起使用,如 in this answer 所示:

    def bar():
        while True:
            key = yield
            # process the key
            # for example
            yield repr(key)
    

    并调用它:

    >>> somebar = bar()
    >>> next(somebar)
    >>> somebar.send('bar')
    "'bar'"
    >>> next(somebar)
    >>> somebar.send(3)
    '3'
    

    【讨论】:

      【解决方案3】:

      假设您面临的问题是从 csv 文件访问键值结构化数据,您有 3 个选项:

      1. 将整个数据加载到字典中,将其作为一个整体复制到 RAM 中,然后具有快速、恒定的访问时间。这就是你说要避免的。
      2. 每次您想通过一个键访问数据时,逐行搜索数据。这没有任何内存开销,但需要每次扫描整个文档,具有线性访问时间。
      3. 使用或将数据复制到某个数据库引擎(或任何键值存储)中,该引擎支持基于磁盘的索引,允许恒定时间访问,而无需先将数据加载到内存中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-16
        • 1970-01-01
        • 2010-09-21
        • 2021-05-07
        • 1970-01-01
        • 2021-09-09
        • 1970-01-01
        • 2023-03-24
        相关资源
        最近更新 更多