Python bir karma sözlüğü
Önbelleğe alma amaçlı bir dict mevcut ALMAK argümanlar önbelleği bir anahtara ihtiyacım var.
Şu anda sha1(repr(sorted(my_dict.items())))
kullanıyorum (sha1()
dahili hashlib kullanan bir kolaylık yöntemi) ama eğer daha iyi bir yolu varsa merak ediyorum.
CEVAP
EDİTBu cevap okumaya devam etmeden önce, lütfen Jack O'Connor bu çok daha kolay (ve daha hızlı) çözümü aşağıda da iç içe sözlükler karma için çalışan (O) bakın.
Cevap olarak kabul edilmiş olsa da, sorunun adı "python bir sözlük" olarak başlık ve cevap eksik. Karma. Soru cesedi ile ilgili olarak, cevap tamamlandı.)
İç İçe Geçmiş Sözlük
Bir arar bir sözlük karması için Yığın Taşması, bir yerinde adlı bu soruyu takılmaları, bir karma iç içe sözlükler çarpma girişiminde ise tatminsiz bırakabilir. Cevap yukarıda bu durumda işe yaramaz, ve özyinelemeli mekanizması bir çeşit karma almak için uygulamak zorunda kalırsınız.
İşte böyle bir düzenek:
import copy
def make_hash(o):
"""
Makes a hash from a dictionary, list, tuple or set to any level, that contains
only other hashable types (including any lists, tuples, sets, and
dictionaries).
"""
if isinstance(o, (set, tuple, list)):
return tuple([make_hash(e) for e in o])
elif not isinstance(o, dict):
return hash(o)
new_o = copy.deepcopy(o)
for k, v in new_o.items():
new_o[k] = make_hash(v)
return hash(tuple(frozenset(sorted(new_o.items()))))
Bonus: Karma Nesneler ve Sınıflar
Karma() işlevi çalışır sınıfları veya örneklerini karma büyük. Ancak, burada bir konuyla ilgili nesneleri olarak karma ile buldum:
class Foo(object): pass
foo = Foo()
print (hash(foo)) # 1209812346789
foo.a = 1
print (hash(foo)) # 1209812346789
Karma foo değiştirdim sonra bile aynıdır. Bu foo kimliğini karma aynıdır değişti, o yüzden alamadım çünkü. Eğer foo farklı akım tanımına bağlı olarak karma yapmak istiyorsanız, çözüm aslında değişen her ne ise karma. Bu durumda, __dict__ niteliği:
class Foo(object): pass
foo = Foo()
print (make_hash(foo.__dict__)) # 1209812346789
foo.a = 1
print (make_hash(foo.__dict__)) # -78956430974785
Sınıfın kendisi ile aynı şeyi yapmak istediğinizde ne yazık ki:
print (make_hash(Foo.__dict__)) # TypeError: unhashable type: 'dict_proxy'
____ Özellik dict sınıfı normal bir sözlük değildir
print (type(Foo.__dict__)) # type <'dict_proxy'>
Burada sınıfları uygun şekilde işleyen bir önceki benzer bir mekanizma
import copy
DictProxyType = type(object.__dict__)
def make_hash(o):
"""
Makes a hash from a dictionary, list, tuple or set to any level, that
contains only other hashable types (including any lists, tuples, sets, and
dictionaries). In the case where other kinds of objects (like classes) need
to be hashed, pass in a collection of object attributes that are pertinent.
For example, a class can be hashed in this fashion:
make_hash([cls.__dict__, cls.__name__])
A function can be hashed like so:
make_hash([fn.__dict__, fn.__code__])
"""
if type(o) == DictProxyType:
o2 = {}
for k, v in o.items():
if not k.startswith("__"):
o2[k] = v
o = o2
if isinstance(o, (set, tuple, list)):
return tuple([make_hash(e) for e in o])
elif not isinstance(o, dict):
return hash(o)
new_o = copy.deepcopy(o)
for k, v in new_o.items():
new_o[k] = make_hash(v)
return hash(tuple(frozenset(sorted(new_o.items()))))
Bu ancak çok istediğiniz bir karma demet döndürmek için kullanabilirsiniz:
# -7666086133114527897
print (make_hash(func.__code__))
# (-7666086133114527897, 3527539)
print (make_hash([func.__code__, func.__dict__]))
# (-7666086133114527897, 3527539, -509551383349783210)
print (make_hash([func.__code__, func.__dict__, func.__name__]))
Python 3 varsayar.NOT: x. Make_hash sanıyorum, ancak önceki sürümleri test etmedi() çalışır,, 2.7.2 söylüyorlar. Bildiğim kadarıyla örnek çalışma yapma, benyapınbiliyorum
func.__code__
ile değiştirilmelidir
func.func_code
Python bir sözlük karma tablo bir örne...
Python karma yerleşik() fonksiyonu...
Sunucu tarafında uygulama (PHP, Ruby, ...
Nasıl bir Python nesne olup olmadığını...
Argparse Python: Nasıl yardım metindek...