3

I have a python dictionary , the dictionary key composed from tupples,

like this :

{
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
 (u'A_String_0', u'B_String_4'): 301, 
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
}

I'd like to remove all keys from dictionary when only part of tupple appears in key :

for example 'Remove_'

In this case , must pop two keys: one contains u'Remove_Me' and another contains u'Remove_Key'

Finally the dictionary will look like this :

{
  (u'A_String_0', u'B_String_4'): 301
}

Thanks a lot !

Toren
  • 6,648
  • 12
  • 41
  • 62

4 Answers4

7

One way:

    >>> d = {
     (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
     (u'A_String_0', u'B_String_4'): 301, 
     (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
    }
    >>> 
    >>> 
    >>> d_out = {k:v for k,v in d.items() if not any(x.startswith('Remove_') for x in k)}
    >>> d_out
{(u'A_String_0', u'B_String_4'): 301}

EDIT: In case you wanted to check if Remove_ is part of any item of the tuple key, then you are better with:

>>> d_out = {k:v for k,v in d.items() if not any('Remove_' in x for x in k)}
Iron Fist
  • 10,739
  • 2
  • 18
  • 34
5

Since keys are always a combined thing without any structure or pattern, you always need to have the full key in order to access elements in the dictionary. In particular this means that you cannot find elements using some partial key. So in order to do this, there is no way other than looking at all keys:

>>> d = {
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
 (u'A_String_0', u'B_String_4'): 301, 
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301}
>>> { k: v for k, v in d.items() if not any(x.startswith('Remove_') for x in k) }
{(u'A_String_0', u'B_String_4'): 301}

This will create a new dictionary from the source dictionary, taking every key k for which any(x.startswith('Remove_') for x in k) is not true. That any() expression will be true if there is an element in x that starts with 'Remove_'.

poke
  • 369,085
  • 72
  • 557
  • 602
2

Using the same dictionnary, not a one-liner though. Also note that original post said "part of tupple appears in key" so it hasn't to be in the beginning i.e startswith()

>>> d = {
...      (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
...      (u'A_String_0', u'B_String_4'): 301, 
...      (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
...     }
>>> for k in d.keys():
...     for i in k:
...         if 'Remove_' in i:
...             del d[k]
...             break
... 
>>> d
{(u'A_String_0', u'B_String_4'): 301}
Seif
  • 1,058
  • 11
  • 19
2

if it is sartswith you have already got your answer. If not then you could use in or re for more complex checking

Code:

import re
dic = {
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
 (u'A_String_0', u'B_String_4'): 301, 
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
}
print {k:v for k,v in dic.items() if not any(re.match("Remove", val)for val in k)} # Using in
print {k:v for k,v in dic.items() if not any("Remove" in val for val in k)} # Using re.match

Output:

{(u'A_String_0', u'B_String_4'): 301}

Note:

  • This would remover the key if Remove occurs any where in the key
The6thSense
  • 8,103
  • 8
  • 31
  • 65