Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve data from nested tuple-dictionary structure using Python list-comprehension

I have a n-tuple of dictionaries. I want to retrieve a dictionary from this tuple that contains a particular key-value pair.

I'm trying to do this as elegantly as possible, and I think a list comprehension is the way to go - but this isn't a basic list comprehension and I'm a little lost.

This shows the idea of what I'm trying to do, but it doesn't work of course:

# 'data' is my n-tuple
# 'myKey' is the key I want
# 'myValue is the value I want

result = [data[x] for dictionary in data if (data[x][myKey]) == myValue)][0]

# which gives this error:

NameError: global name 'x' is not defined

Before, I was trying something like this (the error makes sense and I understand it):

result = [data[x] for x in data if (data[x][myKey] == myValue)][0]

# which gives this error:

TypeError: tuple indices must be integers, not dict

Is this a time to use nested comprehensions? What would that look like, and would it be simpler at that point to just write it out with loops and conditionals?

Also, side question - is there a more pythonic way to get the first (or the only) element in a list besides just slapping [0] on the end?

like image 721
Peter Henry Avatar asked Jun 23 '26 23:06

Peter Henry


2 Answers

The most pythonic way would be to use next():

Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.

data = ({'1': 'test1'}, {'2': 'test2'}, {'3': 'test3'})
myKey = '2'
myValue = 'test2'

print next(x for x in data if x.get(myKey) == myValue)  # prints {'2': 'test2'}

You can also specify a default value in case the item wasn't found:

myKey = 'illegal_key'
myValue = 'illegal_value'

print next((x for x in data if x.get(myKey) == myValue), 
           'No item found')  # prints "No item found"
like image 133
alecxe Avatar answered Jun 26 '26 18:06

alecxe


If you have a tuple of dictionaries called data you can do:

>>> data = ({'fruit': 'orange', 'vegetable':'lettuce'}, {'football':'arsenal', 'basketball':'lakers'}, {'england':'london', 'france':'paris'} )
>>> myKey = "football"
>>> myValue = "arsenal"
>>> [d for d in data if (myKey, myValue) in d.items()][0]
 {'basketball': 'lakers', 'football': 'arsenal'}

This will return the first dictionary in the tuple that contains myKey and myValue using list comprehension (remove [0] to get all dictionaries).

like image 29
jabaldonedo Avatar answered Jun 26 '26 16:06

jabaldonedo