-1
d = {'a1':1, 'a2':2,'a3':3,'a4':1,'a5':1,'b':2, 'c':3}

for k, v in d.copy().items():
    if 'a' in k:
        del d[k]

print(d)

I want to delete elements if the key or value meets a certain requirement, as above, in which the keys containing 'a' will be deleted.

In particular, can I somehow not use the copy() function to do the same thing?

EDIT: Based on suggestion, I adopted this way:

for k in list(d):
    if 'a' in k:
        del d[k]
marlon
  • 6,029
  • 8
  • 42
  • 76
  • 4
    You don't have to copy the entire `dict`, just the keys: `for k in list(d): ...` – chepner Jun 15 '22 at 17:57
  • you need to use `del` in a dict if you want to remove key-value pair from dicionary without rewriting it all – sahasrara62 Jun 15 '22 at 17:59
  • @mozway A `del` solution after all... Did you realize that none of the answers under the question which you claim this duplicates have a `del` solution? – Kelly Bundy Jun 15 '22 at 18:05
  • If just iterating through the keys, I can just do 'for k in d:'. Why should I do list(d)? – marlon Jun 15 '22 at 18:05
  • @marlon try without it ;) – mozway Jun 15 '22 at 18:07
  • Yes, it won't work. Just tried. @mozway – marlon Jun 15 '22 at 18:08
  • what's about using .pop? – Yohann Boniface Jun 15 '22 at 18:11
  • @Kelly then I think OP already had the answer, I just provided a minor variant – mozway Jun 15 '22 at 18:11
  • 1
    @mozway What answer had they had already? I.e., what more efficient than their own code had they already had? (I'm btw not at all convinced that yours is more efficient.) – Kelly Bundy Jun 15 '22 at 18:14
  • I never said it was, just fits in one line, iterating over `list(d)` is likely better ;) – mozway Jun 15 '22 at 18:18
  • @mozway A Python function call per element is not good, though. – Kelly Bundy Jun 15 '22 at 18:26
  • 1
    @mozway [Theirs 4.7 ms, yours 7.7 ms](https://tio.run/##XVDJasMwEL3rK@YWqRXGJpdiyJeEYmR75AyxFiS1iVv67a7lBUp1EXrbjJ6f0s3Z85sP86yDMxBTIDsAGe9CAhU7omZ0Dwydiri8QbUdW5VB2X65dmV3c9ShXFGyifVwge8N5ItFwGuO5jvNKwlVWZZC1PAfAu0CNEA2MwPyDJbih/mQVSNa3gvBWI8aXKCBrBq5qBmsvruEz2zti875iYuCEpq48QCk4aROmb9vQD5exbjFGff1UNOfsKzUNCYMfFSm7RU86yPhKWGkmPIy9Z6x1pLIIKWjloAeVWI5TWfX9VhZ7tPe4QXOeWBaCjNk@ebgWoL9MC2GS7W0tPDb95MEXTSNVQabRszzLw). – Kelly Bundy Jun 15 '22 at 18:33
  • @Kelly and? I never claimed faster speed, at most shorter code – mozway Jun 15 '22 at 18:42
  • @mozway The question doesn't ask for shorter, it asks for more efficient. So you're saying your comment had nothing to do with the question? Usually when people post solutions, they're meant to address the question, that's why I thought you meant it's more efficient. – Kelly Bundy Jun 15 '22 at 18:47
  • I just provided an alternative, not sure why you're obsessed about it. If you wanted to do an interesting comparison, you should have included `list(d)`. – mozway Jun 15 '22 at 18:55
  • Not realized that different ways' performance differ big. If they are called in a loop, that could be a big deal. – marlon Jun 15 '22 at 19:28

1 Answers1

3

Create a new dictionary without the key you want to filter

d = {'a1':1, 'a2':2,'a3':3,'a4':1,'a5':1,'b':2, 'c':3}

filtered_d = {k: v for k,v in d.items() if 'a' not in k}
Yohann Boniface
  • 494
  • 3
  • 10
  • 5
    Sometimes, you really do just want to remove items from an existing `dict`, rather than create a new restricted `dict`. – chepner Jun 15 '22 at 17:57
  • @chepner I tested using the `for k in list(d)` loop with `del` and the dictionary comprehension i proposed here, each on a 10 milions random keys dictionnary. For both, i got a time of that about `0.3` ms. – Yohann Boniface Jun 15 '22 at 18:08
  • 3
    Time isn't the issue; it's whether the dict needs to be modified in-place because some one else is holding a reference to the same object and expects to see the results. – chepner Jun 15 '22 at 18:11
  • I accepted this answer but in my code I chose the in-place modification approach by using list(d), which seems better. – marlon Jun 15 '22 at 18:14