3

dictofの値へのパスをどのように保存するdictのでしょうか? たとえば、name値へのパスを変数に簡単に格納できname_fieldます。

person = {}
person['name'] = 'Jeff Atwood'
person['address'] = {}
person['address']['street'] = 'Main Street'
person['address']['zip'] = '12345'
person['address']['city'] = 'Miami'

# Get name
name_field = 'name'
print( person[name_field] )

値へのパスはどのようcityに保存されますか?

# Get city
city_field = ['address', 'city']
print( person[city_field] )  // Obviously won't work!
4

4 に答える 4

4

reduce関数を使用してこれを行うことができます

print reduce(lambda x, y: x[y], city_field, person)

出力

Miami
于 2013-11-06T12:46:39.627 に答える
1

Simeon (および Unubtu の削除された回答) を使用する別の方法は、追加のメソッドを定義する独自の dict クラスを作成することです。

class mydict(dict):
    def lookup(self, *args):
        tmp = self
        for field in args:
            tmp = tmp[field]
        return tmp

person = mydict()
person['name'] = 'Jeff Atwood'
person['address'] = {}
person['address']['street'] = 'Main Street'
person['address']['zip'] = '12345'
person['address']['city'] = 'Miami'

print(person.lookup('address', 'city'))
print(person.lookup('name'))
print(person.lookup('city'))

結果は次のとおりです。

Miami
Jeff Atwood
Traceback (most recent call last):
  File "look.py", line 17, in <module>
    print(person.lookup('city'))
  File "look.py", line 5, in lookup
    tmp = tmp[field]
KeyError: 'city'

thefourthey の提案に従って、ループを短くすることができます。本当に凝りたいのであれば、プライベート メソッドをオーバーライド__get__して のようなケースを許可することもできますperson['address', 'city']が、そうすると扱いが難しくなる可能性があります。

于 2013-11-06T12:50:22.680 に答える
1

ここに別の方法があります - Simeon Visser のものとまったく同じように動作します

from operator import itemgetter
pget = lambda map, path: reduce(lambda x,p: itemgetter(p)(x), path, map)

あなたのサンプルデータで:

person = {
  'name': 'Jeff Atwood',
  'address': {
    'street': 'Main Street',
    'zip': '12345',
    'city': 'Miami',
  },
}

pget(person, ('address', 'zip')) # Prints '12345'
pget(person, ('name',))          # Prints 'Jeff Atwood'
pget(person, ('nope',))          # Raises KeyError
于 2013-11-06T12:53:09.817 に答える