2

I need the most efficient way to delete few items from the dictionary, RIght now, Im using for stmt as given below..Thinking the same thing should be accomplished in few lines.

for eachitem in dicta:
                del eachitem['NAME']
                del eachitem['STATE']
                del eachitem['COUNTRY']
                del eachitem['REGION']
                del eachitem['LNAME']

dicta = [{'name','Bob','STATE':'VA','COUNTRY':'US','REGION':'MIDWEST','LNAME':'Brian',Salary:6000}]

I want only the salary item in the dictionary once its deleted. Any inputs are appreciated.

user1050619
  • 19,822
  • 85
  • 237
  • 413
  • Can you give us more of an idea as to your data structure? – Logan Feb 21 '13 at 18:05
  • Do you want only the salary item in the dictionary, or do you only want the salary? Just selecting that makes it a lot simpler. – Chris Morgan Feb 21 '13 at 18:22
  • I have not given the full items in the dictionary , it has totally 20 elements and I need to delete only 5 elements...#Mgilson approach is a perfect for me ..thanks – user1050619 Feb 21 '13 at 18:25
  • FWIW , efficiency with stuff like this is largely negligible. readability is often the best approach. – Jonathan Vanasco Feb 21 '13 at 18:29

3 Answers3

6

If your example data is what you are dealing with, instead of deleting the elements, just recreate your dict with that lone key

dicta = [{'Salary':e['Salary']} for e in dicta]

or to me, it makes more sense, to just create a list instead of list of dicts

dicta = [e['Salary'] for e in dicta]

but depends on what you are planning to achieve

Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • Confirmed: this is the fastest method thus posted. See my post. – David Marx Feb 21 '13 at 18:24
  • Yeah, when I posted, there wasn't the statement that OP only wanted to keep 1 key/value pair in the dict. I've updated with a solution that uses `dict.clear` ... Don't know how it compares though. – mgilson Feb 21 '13 at 18:25
  • Oh well if all he wants is one item from the dict then clearly it would be faster to just get that one item than to go through deleting all the others. – David Marx Feb 21 '13 at 18:31
5

I suppose you could use:

for eachitem in dicta:
    for k in ['NAME','STATE','COUNTRY','REGION','LNAME']:
        del eachitem[k]

Or, if you only want 1 key:

for eachitem in dicta:
    salary = eachitem['SALARY']
    eachitem.clear()
    eachitem['SALARY'] = salary

This does everything in place which I assume you want -- Otherwise, you can do it out of place simply by:

eachitem = {'SALARY':eachitem['SALARY']}
mgilson
  • 300,191
  • 65
  • 633
  • 696
1

EDIT: I had said dict comprehension was fastest: I was wrong. I had accidentally run %timeit test3 instead of %timeit test3(). See results below.

def test1():
    dicta = [{'NAME':'Bob','STATE':'VA','COUNTRY':'US','REGION':'MIDWEST','LNAME':'Brian','Salary':6000}]
    remove = ['NAME','STATE','COUNTRY','REGION','LNAME']
    for d in dicta:
        for r in remove:
            d.pop(r)

def test2():
    dicta = [{'NAME':'Bob','STATE':'VA','COUNTRY':'US','REGION':'MIDWEST','LNAME':'Brian','Salary':6000}]
    remove = ['NAME','STATE','COUNTRY','REGION','LNAME']
    for d in dicta:
        for r in remove:
            del d[r]

def test3():
    dicta = [{'NAME':'Bob','STATE':'VA','COUNTRY':'US','REGION':'MIDWEST','LNAME':'Brian','Salary':6000}]
    remove = ['NAME','STATE','COUNTRY','REGION','LNAME']    
    dicta = [{k:v for k,v in d.iteritems() if k not in remove } for d in dicta]

# this is really what OP was looking for, the other 3 tests are more generalized.    
def test4():    
    dicta = [{'NAME':'Bob','STATE':'VA','COUNTRY':'US','REGION':'MIDWEST','LNAME':'Brian','Salary':6000}]
    remove = ['NAME','STATE','COUNTRY','REGION','LNAME']    
    dicta = [e['Salary'] for e in dicta]

%timeit test1()
# 100000 loops, best of 3: 2.32 us per loop    
%timeit test2()
# 1000000 loops, best of 3: 1.68 us per loop    
%timeit test3()
# 100000 loops, best of 3: 3.23 us per loop
%timeit test4()
# 1000000 loops, best of 3: 1.46 us per loop
David Marx
  • 8,172
  • 3
  • 45
  • 66
  • +1: Cannot resist to vote, btw interesting finding `d.pop` is slower than `del`, may be because of function call overhead – Abhijit Feb 21 '13 at 18:28
  • Updated post. I messed up my call to timeit, apparently the conditional dict comprehension is not faster than just using `del` – David Marx Feb 21 '13 at 18:38
  • This gives me a invalid syntax error-dicta = [{k:v for k,v in d.iteritems() if k not in remove } for d in dicta] – user1050619 Feb 21 '13 at 18:47
  • that dict comprehension syntax is only supported for python 2.7+ http://stackoverflow.com/a/1747827/819544 . Try this: `dicta = [dict((k,v) for k,v in d.iteritems() if k not in remove ) for d in dicta]` – David Marx Feb 21 '13 at 18:51