3

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?

3 Answers 3

2

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"
Sign up to request clarification or add additional context in comments.

3 Comments

How will I solve this problem if the tuple data is defined in this manner data = ({"one":'I', "three":'III','five':'V'},{"two":'II',"four":'IV'}) and the myKey = 'one' and myValue ='I'
@kvivek, it works, since the OP asked: I want to retrieve a dictionary from this tuple that contains a particular key-value pair
I don't see why @kvivek's case is a problem; your method worked on it when I tested it. Maybe he misunderstood my question? This answer does what I need, but it requires that a reader understands generators - which I haven't used anywhere else in my code. For consistency I'm going with jabaldonedo's answer.
1

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

Comments

1

But why next? Just use generator. I would do like this (a little changed code from alecxe):

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

result = [data[x] for x in data if data[x] == myValue]

Comments

Your Answer

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.