Remove elements from dict in for loop

How can I delete all elements in a dictionary after a modified one? If the second one is changed, then we delete everything that is behind it or, if the first one is changed, then we delete everything after it and so on.

d = {'first': 'one', 'second': 'two', 'third': 'three'}
k = 'second'

for key in d:
    if k in key:
        d[key] = 'new value'
        # delete third

Upvotes: 0

Views: 202

Answers (4)

LeoE
LeoE

Reputation: 2083

You can use the following code. it makes the dict items into a list and creates a new dict from the remaining items:

d = {'first': 'one', 'second': 'two', 'third': 'three'}
k = 'second'
d[k] = 'NewValue'
d = dict(list(d.items())[:list(d.keys()).index(k)+1])
print(d)

Out:

{'first': 'one', 'second': 'NewValue'}

Out of curiosity I timed it against @Daniel's answer those are my timeit code and result:

import timeit, functools

def test_1(d,k):
    d = dict(list(d.items())[:list(d.keys()).index(k)+1])
    d[k] = 'new vlaue'
    return d

def test_2(d, k):
    new_d = {}
    for key, value in sorted(d.items()):
        if key == k:
            new_d[key] = 'new value'
            break
        new_d[key] = value
    return new_d


if __name__ == '__main__':
    keys = [x for x in range(100000)]
    values = [x for x in range(100000)]

    d = dict(zip(keys, values))
    k = 9999
    a = timeit.timeit(functools.partial(test_1, d, k), number = 1000)
    b = timeit.timeit(functools.partial(test_2, d, k), number = 1000)
    print(a, b)

Output:

5.107241655999815 6.745305094000059

If you change the sorted(...) into list(...) in Daniels answer it is the other way around:

5.046288972999946 4.211456709999993

It is a constant offset, probably due to creating the list out of the dict twice instead of once. So @Daniels answer is both faster and less memory expensive

Upvotes: 1

High-Octane
High-Octane

Reputation: 1112

You should not be using normal dictionary if you're trying to keep them in an order, at least if you're below py3.7 of course.

Please use if you're below 3.7.

We are creating a new dictionary in the below code and removing the old one, you can even put this inside a function and use it.

from collections import OrderedDict

d =OrderedDict([('first','one'), ('second', 'two'), ('third', 'three')])
k = 'second'

output_dict = OrderedDict()
for key,value in d.items():
    if k in key:
        output_dict[key] = value
        break
    else:
        output_dict[key] = value
del d
print(output_dict)

Upvotes: 0

Maede
Maede

Reputation: 182

you can delete rest of dict by keys. like below:

d = {'first': 'one', 'second': 'two', 'third': 'three'}
k = 'first' #for modify

keys = ['second', 'third'] #rest of dict to delete

list(map(d.pop, keys))

it will return {'first':'modified_value'}

Upvotes: 0

Daniel
Daniel

Reputation: 42778

Instead of deleting elements, just create a new dictionary. Since dictionaries are not ordered, you should sort the items in some way.

d = {'first': 'one', 'second': 'two', 'third': 'three'}
k = 'second'

new_d = {}
for key, value in sorted(d.items()):
    if key == k:
        new_d[key] = 'new value'
        break
    new_d[key] = value

Upvotes: 2

Related Questions