1

I want to copy pairs from this dictionary based on their values so they can be assigned to new variables. From my research it seems easy to do this based on keys, but in my case the values are what I'm tracking.

things = ({'alpha': 1, 'beta': 2, 'cheese': 3, 'delta': 4})

And in made-up language I can assign variables like so -

smaller_things =  all values =3 in things 
Community
  • 1
  • 1
Benjamin James
  • 941
  • 1
  • 9
  • 24

3 Answers3

2

You can use .items() to traverse through the pairs and make changes like this:

smaller_things = {}
for k, v in things.items():
    if v == 3:
        smaller_things[k] = v

If you want a one liner and only need the keys back, list comprehension will do it:

smaller_things = [k for k, v in things.items() if v == 3]

>>> things = { 'a': 3, 'b': 2, 'c': 3 }
>>> [k for k, v in things.items() if v == 3]
['a', 'c']
m.brindley
  • 1,218
  • 10
  • 19
  • exactly what I was looking for- Im new to python and recognize everything except that last line- can you explain how that works? – Benjamin James Feb 01 '13 at 05:57
  • @wim I'm running 2.7 and both worked the same way, so it seems. Do you forsee any issues with this? – Benjamin James Feb 01 '13 at 05:59
  • List comprehension is a way of creating lists from complex expressions. In this example, I'm taking all values of k (the key from `.items()`) when v (the value) matches 3. Check out the list comp documentation, they're awesome - http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions – m.brindley Feb 01 '13 at 06:03
  • They will both work the same way, but `iteritems` is more efficient and it's just a good habit to get into to use iterators if you don't actually need to build the whole list in memory. – wim Feb 01 '13 at 06:27
  • @wim I like the sound of that- out of curiosity how much faster are we talking about if my list has 30,000 pairs? – Benjamin James Feb 01 '13 at 06:41
  • 1
    FWIW, should also highlight the syntax in the example for OP: The neat trick not commented on is the multiple assignment. For k,v creates two variables at the same time from the two items in tuples returned by items or iteritems – theodox Feb 01 '13 at 06:54
  • @wim +1 for my first lesson in optimization – Benjamin James Feb 01 '13 at 07:02
  • 1
    Worth noting that some benefits of the implementation of `.iteritems` was rolled into `.items` as part of the 3k changes to dicts. `.items` is preferred for portable code but if you need performance on Py2.x, definitely consider using `.iteritems`. – m.brindley Feb 01 '13 at 10:37
0

kindly this answer is as per my understanding of your question . The dictionary is a kind of hash table , the main intension of dictionary is providing the non integer indexing to the values . The keys in dictionary are just like indexes .

for suppose consider the "array" , the elements in array are addressed by the index , and we have index for the elements not the elements for index . Just like that we have keys(non integer indexes) for values in dictionary .

And there is one implication the values in dictionary are non hashable I mean the values in dictionary are mutable and keys in dictionary are immutable ,simply values could be changed any time .

simply it is not good approach to address any thing by using values in dictionary

neotam
  • 2,611
  • 1
  • 31
  • 53
  • valid point, though I am planning for the values to change. Eventually I will be working with realtime data visualization, so the values will be contributing to the animated "flow" of the visualizations. But again you make an important point regarding best practices when working with dictionaries. – Benjamin James Feb 01 '13 at 06:05
0

you can just reverse the dictionary and pull from that:

keys_values = { 1:"a", 2:"b"}
values_keys = dict(zip(keys_values.values(), keys_values.keys()))
print values_keys
>>>  {"a":1, "b":2}

That way you can do whatever you need to with standard dictionary syntax.

The potential drawback is if you have non-unique values in the original dictionary; items in the original with the same value will have the same key in the reversed dictionary, so you can't guarantee which of the original keys would be the new value. And potentially some values are unhashable (such as lists).

Unless you have a compulsive need to be clever, iterating over items is easier:

for key, val in my_dict.items():
    if matches_condition(val):
        do_something(key)
theodox
  • 12,028
  • 3
  • 23
  • 36