Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve from python dict where key is only partially known?

I have a dict that has string-type keys whose exact values I can't know (because they're generated dynamically elsewhere). However, I know that that the key I want contains a particular substring, and that a single key with this substring is definitely in the dict.

What's the best, or "most pythonic" way to retrieve the value for this key?

I thought of two strategies, but both irk me:

for k,v in some_dict.items():
    if 'substring' in k:
        value = v
        break

-- OR --

value = [v for (k,v) in some_dict.items() if 'substring' in k][0]

The first method is bulky and somewhat ugly, while the second is cleaner, but the extra step of indexing into the list comprehension (the [0]) irks me. Is there a better way to express the second version, or a more concise way to write the first?

like image 541
coredumperror Avatar asked Aug 13 '11 07:08

coredumperror


People also ask

How do I find a dictionary value without a key?

You just have to use dict. values() . This will return a list containing all the values of your dictionary, without having to specify any key.

How do you check if a dictionary has a specific key?

Check If Key Exists Using has_key() The has_key() method is a built-in method in Python that returns true if the dict contains the given key, and returns false if it isn't.

How do you separate a key from a value in a dictionary?

Creating a Dictionary To do that you separate the key-value pairs by a colon(“:”). The keys would need to be of an immutable type, i.e., data-types for which the keys cannot be changed at runtime such as int, string, tuple, etc. The values can be of any type.


2 Answers

There is an option to write the second version with the performance attributes of the first one.

Use a generator expression instead of list comprehension:

value = next(v for (k,v) in some_dict.iteritems() if 'substring' in k)

The expression inside the parenthesis will return an iterator which you will then ask to provide the next, i.e. first element. No further elements are processed.

like image 113
blubb Avatar answered Sep 18 '22 22:09

blubb


How about this:

value = (v for (k,v) in some_dict.iteritems() if 'substring' in k).next()

It will stop immediately when it finds the first match.

But it still has O(n) complexity, where n is the number of key-value pairs. You need something like a suffix list or a suffix tree to speed up searching.

like image 40
wks Avatar answered Sep 19 '22 22:09

wks