Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Check if list of named tuples contains particular attribute value

I have a list of named tuples:

from collections import namedtuple

T = namedtuple('T', ['attr1', 'attr2', 'attr3', 'attr4'])
t1 = T('T1', 1, '1234', 'XYZ')
t2 = T('T2', 2, '1254', 'ABC')
t3 = T('T2', 2, '1264', 'DEF')
l = [t1, t2, t3]

I want to check if an element exists in the list T where attr1 = 'T2'.

Checking if the list contains such an element by doing:

any(x for x in l if x.attr1 == 'T2')

only returns the information whether such a namedtuple is in the list or not.
I would like to also pop this namedtuple from the list.
One way of doing it is:

if any(x for x in l if x.attr1 == 'T2'):
   result = [x for x in l if x.attr1 == 'T2'].pop()

However, I don't like this solution, since I'm looping over the list l twice.

Is there any better/more-elegant way of doing this?

like image 372
Ziva Avatar asked Jul 04 '17 22:07

Ziva


People also ask

How do you get attributes from a Namedtuple?

The attribute values of NamedTuple are ordered. So we can access them using the indexes. The NamedTuple converts the field names as attributes. So using getattr() it is possible to get the data from that attribute.

What is Namedtuple Python?

Python's namedtuple() is a factory function available in collections . It allows you to create tuple subclasses with named fields. You can access the values in a given named tuple using the dot notation and the field names, like in obj.

How do you check if elements of a tuple are same?

When it is required to check if two list of tuples are identical, the '==' operator is used. The '==' operator checks to see if two iterables are equal or not. A list can be used to store heterogeneous values (i.e data of any data type like integer, floating point, strings, and so on).

How do you use named tuples in Python?

To create a named tuple, import the namedtuple class from the collections module. The constructor takes the name of the named tuple (which is what type() will report), and a string containing the fields names, separated by whitespace. It returns a new namedtuple class for the specified fields.


2 Answers

How about an old-school for loop? Simple, elegant, and you loop only once.

for x in l:
    if x.attr1 == 'T2':
        break

result = x
like image 185
cs95 Avatar answered Oct 01 '22 02:10

cs95


If you need one item and don't necessarily want to pop, you can use next with your existing generator expression:

result = next(x for x in l if x.attr1 == 'T2')
like image 39
Moses Koledoye Avatar answered Oct 01 '22 01:10

Moses Koledoye