Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
访问dict元素的最具python风格的方法_Python_Dictionary - Fatal编程技术网

访问dict元素的最具python风格的方法

访问dict元素的最具python风格的方法,python,dictionary,Python,Dictionary,我多次调用API,最终将结果写入CSV。我有以下代码从dict中提取数据: dict的结构位于Pastebin上,因为它占用了很多空间 如何用更少的代码获得相同的结果?编写一个帮助函数,让您编写更少的样板文件: def follow(obj, path): for seg in path.split(): obj = obj[int(seg) if seg.isdigit() else seg] return obj 电话: prop = follow(

我多次调用API,最终将结果写入CSV。我有以下代码从dict中提取数据:

dict的结构位于Pastebin上,因为它占用了很多空间


如何用更少的代码获得相同的结果?

编写一个帮助函数,让您编写更少的样板文件:

def follow(obj, path):
     for seg in path.split():
          obj = obj[int(seg) if seg.isdigit() else seg]
     return obj
电话:

prop = follow(data, "property 0")
city = follow(prop, "address locality")

等等。

编写一个帮助函数,让您编写更少的样板文件:

def follow(obj, path):
     for seg in path.split():
          obj = obj[int(seg) if seg.isdigit() else seg]
     return obj
电话:

prop = follow(data, "property 0")
city = follow(prop, "address locality")

等等。

创建自己的dictionary类怎么样

class DictQuery(dict):
    def get(self, path, default = None):
          keys = path.split("/")
          val = None

          for key in keys:
              if val:
                  if isinstance(val, list):
                      val = [ v.get(key, default) if v else None for v in val]
                  else:
                      val = val.get(key, default)
              else:
                  val = dict.get(self, key, default)

              if not val:
                  break;

          return val
那么,你可以这样称呼它

for row in csv:
    print(DictQuery(row).get("property/address"))

注意,这是未经测试的,只是供您尝试的一个想法。

创建自己的dictionary类怎么样

class DictQuery(dict):
    def get(self, path, default = None):
          keys = path.split("/")
          val = None

          for key in keys:
              if val:
                  if isinstance(val, list):
                      val = [ v.get(key, default) if v else None for v in val]
                  else:
                      val = val.get(key, default)
              else:
                  val = dict.get(self, key, default)

              if not val:
                  break;

          return val
property = data['property'][0]
city = property['address']['locality'] #etc.
那么,你可以这样称呼它

for row in csv:
    print(DictQuery(row).get("property/address"))

注意,这是未经测试的,只是一个供您尝试的想法。

您这样做的方式是python式的。但是,还有其他替代方法,其中一种方法是使用关键帧,就像它们是对象或子对象属性一样。不管它有多像蟒蛇,都在旁观者的眼里。一旦脚手架就位,它肯定需要更少的打字,我觉得它也更可读

property = data['property'][0]
city = property['address']['locality'] #etc.
实现类似功能的一种方法是创建一个dict子类,它是自己的dict子类。一旦定义了类,则必须将其中最外层和所有子字典转换为AttrDict实例

下面的代码显示了我的意思:

import json

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self


def convert(d):
    """ Convert dict "d" and all nested dictionaries in it into AttrDicts. """
    def _decode_dict(a_dict):
        return AttrDict(a_dict)  # Turn each dictionary into an AttrDict

    json_repr = json.dumps(d)
    return json.loads(json_repr, object_hook=_decode_dict)

d = {u'status': {u'code': 0, u'pagesize': 10, u'version': u'1.0.0', u'msg': u'SuccessWithResult', u'total': 1, u'page': 1}, u'property': [{u'building': {u'summary': {u'bldgsNum': 1, u'unitsCount': u'0', u'archStyle': u'OLD', u'bldgType': u'SINGLE FAMILY', u'yearbuilteffective': 0, u'levels': 1, u'storyDesc': u'SINGLE FAMILY'}, u'construction': {u'roofcover': u'ASPHALT SHINGLE', u'wallType': u'WOOD SIDING', u'foundationtype': u'PIER', u'condition': u'FAIR'}, u'rooms': {u'bathstotal': 1.0, u'roomsTotal': 6, u'bathscalc': 1.0, u'bathfixtures': 0, u'bathsfull': 0, u'beds': 3, u'baths3qtr': 0, u'baths1qtr': 0, u'bathshalf': 0}, u'parking': {u'prkgType': u'DETACHED GARAGE', u'prkgSize': 0, u'garagetype': u'DETACHED GARAGE', u'prkgSpaces': u'0'}, u'interior': {u'fplctype': u'TYPE UNKNOWN', u'fplccount': 1, u'bsmtsize': 0, u'fplcind': u'Y'}, u'size': {u'universalsize': 1022, u'livingsize': 1022, u'sizeInd': u'LIVING SQFT ', u'grosssizeadjusted': 0, u'groundfloorsize': 1022, u'bldgsize': 1022, u'grosssize': 0}}, u'area': {u'taxcodearea': u'11', u'countrysecsubd': u'Bexar County', u'muncode': u'21', u'subdname': u'SOUTH PARK TERRACE BAITYS BL 3', u'countyuse1': u'A1', u'blockNum': u'11', u'munname': u'SAN ANTONIO'}, u'vintage': {u'lastModified': u'2017-9-23', u'pubDate': u'2017-10-12'}, u'utilities': {u'heatingtype': u'FORCED AIR', u'wallType': u'WOOD SIDING', u'coolingtype': u'AC.CENTRAL'}, u'summary': {u'proptype': u'SFR', u'propsubtype': u'SINGLE FAMILY', u'absenteeInd': u'SITUS FROM SALE (ABSENTEE)', u'propclass': u'Single Family Residence / Townhouse', u'yearbuilt': 1930, u'legal1': u'NCB 3130 BLK 11 LOT 35 AND 36', u'propIndicator': u'10', u'propLandUse': u'SFR'}, u'location': {u'distance': 0.0, u'elevation': 0.0, u'longitude': u'-98.484597', u'latitude': u'29.396664', u'geoid': u'CO48029,CS4893407,DB4838730,MT30003336,ND0000206694,ND0000567797,PL4865000,RS0000576252,SB0000123866,SB0000123853,SB0000123848,ZI78210', u'accuracy': u'Street'}, u'lot': {u'lotnum': u'35', u'depth': 133, u'lotsize2': 5320, u'frontage': 40, u'lotsize1': 0.1221}, u'address': {u'matchCode': u'ExaStr', u'postal2': u'3873', u'postal3': u'C002', u'locality': u'San Antonio', u'country': u'US', u'countrySubd': u'TX', u'line2': u'SAN ANTONIO, TX 78210', u'line1': u'202 LORETTA PL', u'postal1': u'78210', u'oneLine': u'202 LORETTA PL, SAN ANTONIO, TX 78210'}, u'identifier': {u'apn': u'031300110350', u'apnOrig': u'03130-011-0350', u'fips': u'48029', u'obPropId': 12253857148029}}]}

data = convert(d)
city = data.property[0].address.locality
print(city)  # -> San Antonio
zip_code = data.property[0].address.postal1
print(zip_code)  # -> 78210
county = data.property[0].area.countrysecsubd
print(county)  # -> Bexar County
# and so on and so forth...

你做这件事的方式很像蟒蛇。但是,还有其他替代方法,其中一种方法是使用关键帧,就像它们是对象或子对象属性一样。不管它有多像蟒蛇,都在旁观者的眼里。一旦脚手架就位,它肯定需要更少的打字,我觉得它也更可读

实现类似功能的一种方法是创建一个dict子类,它是自己的dict子类。一旦定义了类,则必须将其中最外层和所有子字典转换为AttrDict实例

下面的代码显示了我的意思:

import json

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self


def convert(d):
    """ Convert dict "d" and all nested dictionaries in it into AttrDicts. """
    def _decode_dict(a_dict):
        return AttrDict(a_dict)  # Turn each dictionary into an AttrDict

    json_repr = json.dumps(d)
    return json.loads(json_repr, object_hook=_decode_dict)

d = {u'status': {u'code': 0, u'pagesize': 10, u'version': u'1.0.0', u'msg': u'SuccessWithResult', u'total': 1, u'page': 1}, u'property': [{u'building': {u'summary': {u'bldgsNum': 1, u'unitsCount': u'0', u'archStyle': u'OLD', u'bldgType': u'SINGLE FAMILY', u'yearbuilteffective': 0, u'levels': 1, u'storyDesc': u'SINGLE FAMILY'}, u'construction': {u'roofcover': u'ASPHALT SHINGLE', u'wallType': u'WOOD SIDING', u'foundationtype': u'PIER', u'condition': u'FAIR'}, u'rooms': {u'bathstotal': 1.0, u'roomsTotal': 6, u'bathscalc': 1.0, u'bathfixtures': 0, u'bathsfull': 0, u'beds': 3, u'baths3qtr': 0, u'baths1qtr': 0, u'bathshalf': 0}, u'parking': {u'prkgType': u'DETACHED GARAGE', u'prkgSize': 0, u'garagetype': u'DETACHED GARAGE', u'prkgSpaces': u'0'}, u'interior': {u'fplctype': u'TYPE UNKNOWN', u'fplccount': 1, u'bsmtsize': 0, u'fplcind': u'Y'}, u'size': {u'universalsize': 1022, u'livingsize': 1022, u'sizeInd': u'LIVING SQFT ', u'grosssizeadjusted': 0, u'groundfloorsize': 1022, u'bldgsize': 1022, u'grosssize': 0}}, u'area': {u'taxcodearea': u'11', u'countrysecsubd': u'Bexar County', u'muncode': u'21', u'subdname': u'SOUTH PARK TERRACE BAITYS BL 3', u'countyuse1': u'A1', u'blockNum': u'11', u'munname': u'SAN ANTONIO'}, u'vintage': {u'lastModified': u'2017-9-23', u'pubDate': u'2017-10-12'}, u'utilities': {u'heatingtype': u'FORCED AIR', u'wallType': u'WOOD SIDING', u'coolingtype': u'AC.CENTRAL'}, u'summary': {u'proptype': u'SFR', u'propsubtype': u'SINGLE FAMILY', u'absenteeInd': u'SITUS FROM SALE (ABSENTEE)', u'propclass': u'Single Family Residence / Townhouse', u'yearbuilt': 1930, u'legal1': u'NCB 3130 BLK 11 LOT 35 AND 36', u'propIndicator': u'10', u'propLandUse': u'SFR'}, u'location': {u'distance': 0.0, u'elevation': 0.0, u'longitude': u'-98.484597', u'latitude': u'29.396664', u'geoid': u'CO48029,CS4893407,DB4838730,MT30003336,ND0000206694,ND0000567797,PL4865000,RS0000576252,SB0000123866,SB0000123853,SB0000123848,ZI78210', u'accuracy': u'Street'}, u'lot': {u'lotnum': u'35', u'depth': 133, u'lotsize2': 5320, u'frontage': 40, u'lotsize1': 0.1221}, u'address': {u'matchCode': u'ExaStr', u'postal2': u'3873', u'postal3': u'C002', u'locality': u'San Antonio', u'country': u'US', u'countrySubd': u'TX', u'line2': u'SAN ANTONIO, TX 78210', u'line1': u'202 LORETTA PL', u'postal1': u'78210', u'oneLine': u'202 LORETTA PL, SAN ANTONIO, TX 78210'}, u'identifier': {u'apn': u'031300110350', u'apnOrig': u'03130-011-0350', u'fips': u'48029', u'obPropId': 12253857148029}}]}

data = convert(d)
city = data.property[0].address.locality
print(city)  # -> San Antonio
zip_code = data.property[0].address.postal1
print(zip_code)  # -> 78210
county = data.property[0].area.countrysecsubd
print(county)  # -> Bexar County
# and so on and so forth...

我能想到的唯一一件事是创建一个较短的别名prop=data['property'][0]您可以按照@Julien的建议,然后执行类似或的操作,使它更干净,但不太像pythonic。也就是说,这是处理字典的一种非常非标准的方式,可能会让其他开发人员(即未来的您)感到困惑。我唯一能想到的是创建一个较短的别名prop=data['property'][0]您可以按照@Julien的建议,然后执行类似或的操作,使它更干净,但不那么像pythonic。也就是说,这是处理字典的一种非常非标准的方式,可能会让其他开发人员(即未来的您)感到困惑。我非常喜欢这个解决方案。。但是在本例中-d={0:'digit zero',0':'str 0'},它将始终返回'digit zero'。是的,它假定您没有字符串数字键。您可以为实整数添加一些特殊语法,例如0。我非常喜欢这个解决方案。。但是在本例中-d={0:'digit zero',0':'str 0'},它将始终返回'digit zero'。是的,它假定您没有字符串数字键。您可以为实整数添加一些特殊语法,例如0。为什么不测试它?为什么不测试它?