-1
>>> cache = {}
>>> cache['1'] = 'long string'
>>> cache['2'] = 'very long string'
>>> buffer = {}
>>> buffer['1'] = cache['1']
>>> del cache['1']
>>> buffer['2'] = cache['2']
>>> del cache['2']
>>> cache
{}
>>> buffer
{'1': 'long string', '2': 'very long string'}

I have two large dictionaries(i.e. cache and buffer). Periodically, I need to move the content from cache to buffer and delete the copied item from cache.

Does Python offer similar function to C++11 std::move so that I don't have to make an extra copy of the item which will be removed later?

Updated based on comments from @JETM

>>> cache = {}
>>> cache['1'] = 'long string2'
>>> buffer['1'] = cache['1']
>>> id(buffer['1'])
139639957636576
>>> id(cache['1'])
139639957636576
>>> del cache['1']
>>> id(buffer['1'])
139639957636576

It looks like the value of cache['1'] is NOT copied into buffer['1'].

q0987
  • 34,938
  • 69
  • 242
  • 387
  • @vaultah, I want to avoid copying the value of cache['1'] and cache['2'] to buffer since these values will be deleted. In C++11, we can avoid the copy with the std::move. – q0987 May 15 '18 at 12:56
  • 2
    Can't you use pop for that? https://www.tutorialspoint.com/python/list_pop.htm – Isma May 15 '18 at 12:57
  • what is the problem? why not use `dict.pop(key)` and `dict.update( {key:value} )`? – mzoll May 15 '18 at 12:58
  • 1
    You're only copying the references; you're not actually copying the string contents. It is not expensive to copy a reference to a long string. – khelwood May 15 '18 at 12:58
  • @vaultah, so you mean the buffer simply holds reference to original cache content until the value is changed? – q0987 May 15 '18 at 12:58
  • 1
    @MarcelZoll better: `d[key] = value` – Jean-François Fabre May 15 '18 at 12:58
  • 1
    https://stackoverflow.com/questions/19721002/is-a-variable-the-name-the-value-or-the-memory-location –  May 15 '18 at 12:59
  • 1
    @q0987 yes, as is the case with the most dynamically typed languages (though not only, see Java). Basically if the language doesn't have proper value semantics, it has no use for `move`. Also, keep in mind that python strings are immutable. – Dan M. May 15 '18 at 13:04
  • 1
    Perhaps it's a case of premature optimization. – Gabriel May 15 '18 at 13:05
  • @DanM. In the real application, the value is not a string instead it holds content of a file. Here, I only use string for demo. Thx – q0987 May 15 '18 at 13:07
  • 2
    @q0987 In most cases, the contents of a file are a string (or a `bytes`, which behaves similarly), unless you're talking about the file object (what gets returned from `open(...)`). In either case, no data gets copied, since Python has no implicit way to refer to the underlying object; you only have references, so you can only copy/make more references. The exception to that rule is the `copy` module, which allows you to explicitly duplicate underlying objects into a new location in memory. – scnerd May 15 '18 at 13:10
  • 2
    @q0987 same thing. In case you were confused by the python `del`/C++ `delete` similarity - their functions are not the same. Python uses GC and has no explicit memory control and the created objects are deleted only then GC decides that no one uses them. It's not unique to Python and same behavior can be found in a variety of languages. – Dan M. May 15 '18 at 13:25

1 Answers1

6

In this particular case, you could use dict.pop:

buffer['1'] = cache.pop('1')

It's worth noting, though, that in Python objects are more synonymous with pointers; that is, when you perform this copy, no data gets duplicated, you're just adding a reference to the object in buffer and removing a reference to it from cache. That is, only the pointer is getting copied.

scnerd
  • 5,836
  • 2
  • 21
  • 36