9

I need to obtain, for each feature of a layer, a dictionary with the attribute names and their values using PyQGIS.

I can get all the attributes of the layer using

indiv = QgsProject.instance().mapLayersByName('Individuos')[0]

for feature in features:
    value = feature[field.name()]
    attrs = feature.attributes()
    print(attrs)

But what I need is to create a dictionary with field names as key and their value for each feature.

1
  • There's a bit of code between indiv= and for feature in features: that you've not shown. One line to get features from the layer and another to get field, or better still all the field names.
    – Spacedman
    Sep 16 '20 at 10:09
12

QgsJsonUtils class has exportAttributes method for getting attributes as dict.

Solution 1:

Making a dictionary including feature id as key, attributes map as value:

{feature1.id: {attr1: value, attr2: value, ...},
 feature2.id: {attr1: value, attr2: value, ...},
 ...}
layer = QgsProject.instance().mapLayersByName('LAYER_NAME')[0]
features_dict = {f.id(): QgsJsonUtils.exportAttributes(f) for f in layer.getFeatures()}

Solution 2:

Making a list including attributes map (dict) of features:

[{attr1: value, attr2: value, ...}, # feature 1
 {attr1: value, attr2: value, ...}, # feature 2
 ...]
layer = QgsProject.instance().mapLayersByName('LAYER_NAME')[0]
features_list = [QgsJsonUtils.exportAttributes(f) for f in layer.getFeatures()]
1
  • Your solution 1 is perfect for what I'm looking. Thanks as always. Sep 16 '20 at 11:11
8

The snippet below should help you. It just prints a dictionary for each feature to the console, but you could do something else with the feature attribute dictionaries if you wanted.

layer = iface.activeLayer()

def print_atts_dict(layer, feature):
    flds = [f for f in layer.fields()]
    atts = {}
    for f in flds:
        atts[f.name()] = feature[f.name()]
    print(atts)
    
for f in layer.getFeatures():
    print_atts_dict(layer, f)
4
# get the fields and features:
fields = indiv.fields()
features = indiv.getFeatures()

# initialise an empty dict with each field name:
attdict = {}
for field in fields:
    attdict[field.name()] = []

# for each field in each feature, append the relevant field data to the dict item:
for feature in features:
  for field in fields:
    v = feature[field.name()]
    attdict[field.name()].append(v)

print(attdict)

That gives a dict that looks like this for some Ghana regions:

{'shapeName': ['Greater Accra', 'Central', 'Western', 'Eastern', 'Ashanti', 'Volta', 'Brong Ahafo', 'Northern', 'Upper West', 'Upper East'],
 'shapeISO': ['GH-AA', 'GH-CP', 'GH-WP', 'GH-EP', 'GH-AH', 'GH-TV', 'GH-BA', 'GH-NP', 'GH-UW', 'GH-UE'],
 'shapeID': ['GHA-ADM1-1590546715-B1', 'GHA-ADM1-1590546715-B2', 'GHA-ADM1-1590546715-B3', 'GHA-ADM1-1590546715-B4', 'GHA-ADM1-1590546715-B5', 'GHA-ADM1-1590546715-B6', 'GHA-ADM1-1590546715-B7', 'GHA-ADM1-1590546715-B8', 'GHA-ADM1-1590546715-B9', 'GHA-ADM1-1590546715-B10'],
 'shapeGroup': ['GHA', 'GHA', 'GHA', 'GHA', 'GHA', 'GHA', 'GHA', 'GHA', 'GHA', 'GHA'], 'shapeType': ['ADM1', 'ADM1', 'ADM1', 'ADM1', 'ADM1', 'ADM1', 'ADM1', 'ADM1', 'ADM1', 'ADM1']}

Which I think is what you are after.

2

The easiest way is using the underdog Geo Interface:

layer = iface.activeLayer()
    
for feature in layer.getFeatures():
    attributes = feature.__geo_interface__["properties"]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.