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.

Taras
35.8k5 gold badges77 silver badges151 bronze badges
asked Jan 15, 2021 at 7:37

2 Answers 2

14

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'), ...).

Taras
35.8k5 gold badges77 silver badges151 bronze badges
answered Jan 15, 2021 at 10:36
2
  • 1
    No need list(), if pairs will be used in a loop (like for p in pairs). Thanks. Commented Jan 15, 2021 at 12:15
  • 1
    you can also put into a dict instead of list, that would make it easy to call by keys later Commented Jul 6, 2023 at 5:01
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')]
Taras
35.8k5 gold badges77 silver badges151 bronze badges
answered Jan 15, 2021 at 7:52
0

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.