11

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:

from qgis.core import QgsProject
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.

Taras
35.7k5 gold badges77 silver badges151 bronze badges
asked Sep 16, 2020 at 9:46
0

5 Answers 5

16

The QgsJsonUtils class has exportAttributes method for getting attributes as a 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, ...},
 ...}
from qgis.core import QgsProject
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
 ...]
from qgis.core import QgsProject
layer = QgsProject.instance().mapLayersByName('LAYER_NAME')[0]
features_list = [QgsJsonUtils.exportAttributes(f) for f in layer.getFeatures()]
Taras
35.7k5 gold badges77 silver badges151 bronze badges
answered Sep 16, 2020 at 10:43
0
11

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.

from qgis.utils import iface
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)
Taras
35.7k5 gold badges77 silver badges151 bronze badges
answered Sep 16, 2020 at 9:52
5

The easiest way is using the underdog __geo_interface__, that was defined by Sean Gillies at https://gist.github.com/sgillies/2217756:

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

References:

Taras
35.7k5 gold badges77 silver badges151 bronze badges
answered Apr 23, 2021 at 13:07
5
# 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.

Taras
35.7k5 gold badges77 silver badges151 bronze badges
answered Sep 16, 2020 at 10:20
3

Another solution utilizes the attributeMap() method of the QgsFeature class.

Returns the feature's attributes as a map of the field name to value.

from qgis.utils import iface
from PyQt5.QtCore import QDate
layer = iface.activeLayer()
for feat in layer.getFeatures():
 attributes = feat.attributeMap()
 attributes_ = {key : value if not isinstance(value, QDate) else value.toString("dd.MM.yyyy") for key, value in attributes.items()}
 print(feat.id(), attributes_)

That results into:

0 {'ColumnA': '1, Michigan Street, Michigan', 'ColumnB': 'Michigan Street', 'ColumnC': '01.05.2023', 'id': 1, 'integer': NULL, 'real': 15.15, 'string': 'Some Text', 'trouble': 'a'}
1 {'ColumnA': NULL, 'ColumnB': NULL, 'ColumnC': '30.04.2023', 'id': 2, 'integer': 100, 'real': NULL, 'string': 'Some Text', 'trouble': 'b'}
2 {'ColumnA': NULL, 'ColumnB': NULL, 'ColumnC': '02.05.2023', 'id': 3, 'integer': 100, 'real': 5.25, 'string': NULL, 'trouble': 'c'}
3 {'ColumnA': NULL, 'ColumnB': NULL, 'ColumnC': NULL, 'id': 4, 'integer': NULL, 'real': NULL, 'string': NULL, 'trouble': 'd'}
4 {'ColumnA': NULL, 'ColumnB': NULL, 'ColumnC': '03.05.2023', 'id': 5, 'integer': NULL, 'real': 10.1, 'string': 'Some Text', 'trouble': 'e'}

Note: There was performed one more additional step due to the type of an attribute - QDate() class which will appear as PyQt5.QtCore.QDate(2023, 5, 3) when one simply applies the feat.attributeMap().

answered May 20, 2023 at 8:06

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.