Newbie question: eliminating entries in dict

S

sean

I have two dictionaries.

a = {'a1': 1, 'a2': 5, 'a3': 2, 'a4': 7}
b = {'something*a4': 1, 'something*something': 1,
'somethingelse*somethingelse': 1, 'something*a1: 1}

What would be an efficient way of eliminating all entries in b which contain
an entry from a.

Such that the result would be

c = ['something*something', 'somethingelse*somethingelse']

or better still
c = {'something*something': 1, 'something*something': 1}

I tried a few different approaches, but they seem very long and unnecessary.
Also searched the mailing list archives and newsgroups and could not come up
with anything.

I know that I will need to compare the .split("*", 1)[1] part of b with
those from a, but am not sure
how to implement it.

Thanks in advance for any help
 
P

Peter Otten

sean said:
I have two dictionaries.

a = {'a1': 1, 'a2': 5, 'a3': 2, 'a4': 7}
b = {'something*a4': 1, 'something*something': 1,
'somethingelse*somethingelse': 1, 'something*a1: 1}

What would be an efficient way of eliminating all entries in b which
contain an entry from a.

Such that the result would be

c = ['something*something', 'somethingelse*somethingelse']

or better still
c = {'something*something': 1, 'something*something': 1}

I tried a few different approaches, but they seem very long and
unnecessary. Also searched the mailing list archives and newsgroups and
could not come up with anything.

I know that I will need to compare the .split("*", 1)[1] part of b with
those from a, but am not sure
how to implement it.

Thanks in advance for any help
dict([(k,v) for k, v in b.iteritems() if k.split("*", 1)[1] not in a])
{'something*something': 1, 'somethingelse*somethingelse': 1}

Two newbie collegues? If you really want to learn something in the process,
a homemade for-loop beats that list comprehension thingy copied from usenet
anytime :)


Peter
 
S

sean

I had tried something very similar to that but ended up with the same error
I am getting now.

Traceback (most recent call last):
File "C:\Python23\trial.py", line 93, in -toplevel-
d = ([(k,v) for k, v in a.iteritems() if (k.split("*", 1)[1]) not in b])
IndexError: list index out of range

Changing the [1] to a [0] makes the Error go away, but compares the wrong
part of the entry.

Any ideas?
 
S

sean

I don't understand how this would be possible since I am splitting the entry
into two parts, shouldn't the index of 1 always exist?
 
P

Peter Otten

sean said:
I had tried something very similar to that but ended up with the same
error I am getting now.

Traceback (most recent call last):
File "C:\Python23\trial.py", line 93, in -toplevel-
d = ([(k,v) for k, v in a.iteritems() if (k.split("*", 1)[1]) not in
b])
IndexError: list index out of range

Changing the [1] to a [0] makes the Error go away, but compares the wrong
part of the entry.

Any ideas?

Assuming you are using the same variable names as in your original post,
it's not similar enough :-( You swapped a and b. Actually, a string is only
split in n+1 parts if it contains at least n separators:
"a-b".split("-", 1) ['a', 'b']
"a-b".split("-", 2) ['a', 'b']
"a-b".split("-", 3) ['a', 'b']
"a".split("-", 1) ['a']
"a-b-c-d".split("-", 1) ['a', 'b-c-d']

Get the idea?

A more robust approach would be:

def keepItem(email, black):
try:
dom = email.split("@")[1]
except IndexError:
return False # discard malformed entries
return dom not in black

good = [(addr, freq) for addr, freq in emails.iteritems() if keepItem(addr,
black)]

Note the use of suggestive variable names to make the code easier to read
and debug.
By the way, when you are still developing your understanding of Python, an
error is easier to find in a small commandline example than in a line
somewhere in a larger script.

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top