Использование словаря Python как (невложенный) ключ

Незначительная модификация ответа Триптиха, позволяющая фактически записать файл (python3):

from urllib.request import urlopen

def chunk_report(bytes_so_far, chunk_size, total_size):
    percent = float(bytes_so_far) / total_size
    percent = round(percent*100, 2)
    sys.stdout.write("Downloaded %d of %d bytes (%0.2f%%)\r" %
                     (bytes_so_far, total_size, percent))

    if bytes_so_far >= total_size:
        sys.stdout.write('\n')


def chunk_read(response, chunk_size=8192, report_hook=None):
    total_size = response.info().get("Content-Length").strip()
    total_size = int(total_size)
    bytes_so_far = 0
    data = b""

    while 1:
        chunk = response.read(chunk_size)
        bytes_so_far += len(chunk)

        if not chunk:
            break

        if report_hook:
            report_hook(bytes_so_far, chunk_size, total_size)

        data += chunk

    return data

Использование:

with open(out_path, "wb") as f:
    response = urlopen(filepath)
    data_read = chunk_read(response, report_hook=chunk_report)

    f.write(data_read)
25
задан 12 revs, 2 users 99% 23 May 2017 в 12:02
поделиться

7 ответов

Если у вас действительно неизменяемый словарь (хотя мне непонятно, почему вы просто не используете список пар: например, [('content-type', 'text / plain'), ('host', 'example.com')] ), затем вы можете преобразовать свой dict в:

  1. Набор пар. Вы уже сделали это в своем вопросе.

  2. Замороженный набор. Это более подходящий подход с математической точки зрения, так как он требует только отношения равенства для элементов вашего неизменяемого dict , тогда как первый подход требует отношения упорядочения помимо равенства .

     >>> frozenset (a.items ())
    
58
ответ дан 28 November 2019 в 18:01
поделиться

Если бы мне нужно было использовать словари в качестве ключей, я бы превратил словарь в кортеж кортежей.

Этот вопрос SO может оказаться полезным: Как лучше всего реализовать вложенные словари?

А вот пример плоского модуля, который будет сглаживать словари: http://yawpycrypto.sourceforge.net/html/public/Flatten.Flatten-module.html

Я не знаю Я не полностью понимаю ваш вариант использования, и я подозреваю, что вы пытаетесь преждевременно оптимизировать то, что не требует оптимизации.

8
ответ дан 28 November 2019 в 18:01
поделиться

One way to do this would be to subclass the dict and provide a hash method. ie:

class HashableDict(dict):
    def __hash__(self):
        return hash(tuple(sorted(self.iteritems())))

>>> d = HashableDict(a=1, b=2)
>>> d2 = { d : "foo"}
>>> d2[HashableDict(a=1, b=2)]
"foo"

However, bear in mind the reasons why dicts (or any mutable types) don't do this: mutating the object after it has been added to a hashtable will change the hash, which means the dict will now have it in the wrong bucket, and so incorrect results will be returned.

If you go this route, either be very sure that dicts will never change after they have been put in the other dictionary, or actively prevent them (eg. check that the hash never changes after the first call to __hash__, and throw an exception if not.)

4
ответ дан 28 November 2019 в 18:01
поделиться

Hmm, isn't your use case just memoizing function calls? Using a decorator, you will have easy support for arbitrary functions. And yes, they often pickle the arguments, and using circular reasoning, this works for non-standard types as long as they can be pickled.

See e.g. this memoization sample

3
ответ дан 28 November 2019 в 18:01
поделиться

To turn a someDictionary into a key, do this

key = tuple(sorted(someDictionary .items())

You can easily reverse this with dict( key )

3
ответ дан 28 November 2019 в 18:01
поделиться

Я не понимаю, зачем вам вообще это нужно, но если вам действительно нужно, вы можете попробовать поправить словарь:

mydict = {"a":1, "b":{"c":10}}
import pickle
key = pickle.dumps(mydict)

d[key] = value
0
ответ дан 28 November 2019 в 18:01
поделиться

Не знаю, правильно ли я понял ваш вопрос, но я попробую

    d[repr(a)]=value

Вы можете взаимодействовать со словарем следующим образом

for el1 in d:
        for el2 in eval(el1):
                print el2,eval(el1)[el2]
-1
ответ дан 28 November 2019 в 18:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: