12

There are "Code" and "Color" fields in my layer like this: (Sample 6 rows)

Code Color
A Red
B Blue
A Red
A Red
B Blue
C Green

All As are Red, all Bs are Blue and so on.

I can get the unique values for each field:

layer = iface.activeLayer()

code_index = layer.fields().indexFromName("Code")
code_unique = layer.uniqueValues(code_index)

color_index = layer.fields().indexFromName("Color")
color_unique = layer.uniqueValues(color_index)

print(code_unique)
print(color_unique)

# OUTPUT
# {'A', 'C', 'B'}
# {'Blue', 'Red', 'Green'}

As you can see, the order of two outputs doesn't match. (When you try, you might get an ordered result, but it depends and is not reliable)

How can I get unique value pairs like [('A', 'Red'), ('B', 'Blue'), ('C', 'Green')] using PyQGIS?

I couldn't find groupby-like method. It can be done by means of groupby(["Code", "Color"]).first() in GeoPandas.

2 Answers 2

12

You can use set() which is a Python built-in function.

layer = iface.activeLayer()    

pairs = list(set([(f["Code"], f["Color"]) for f in layer.getFeatures()]))

print(pairs) # [('A', 'Red'), ('C', 'Green'), ('B', 'Blue')]

A set() is an unordered data structure, so it does not preserve the insertion order. You will probably get an unordered but a matched list (('A', 'Red') ('C', 'Green'), ...).

1
  • 1
    No need list(), if pairs will be used in a loop (like for p in pairs). Thanks. Jan 15, 2021 at 12:15
10

You can use the class Counter() from the collections module.

from collections import Counter

layer = iface.activeLayer()

c = Counter([(feat['Code'],feat['Color']) for feat in layer.getFeatures()])
print(c) # Counter({('A', 'Red'): 3, ('B', 'Blue'): 2, ('C', 'Green'): 1})

combination = [comb for comb in c]
print(combination) # [('A', 'Red'), ('B', 'Blue'), ('C', 'Green')]
0

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.