Tom Kealy
Tom Kealy

Reputation: 2669

Slicing strings in a comprehension

I'm I need to slice the leading character off the valued a dictionary - but only if the length of the value is greater than 1. Currently I'm doing this with a dictionary comprehension:

new_dict = {item[0]:item[1][1:] for item in old_dict if item.startswith('1')}

but I don't know how to modify this so that keys of length one are left alone.

The keys are the codewords of a Huffman code, and so start with '0' or '1'.

An example code is:

code = {'a':'0', 'b':'10', 'c':'110', 'd':'111'}

The above code works fine for 'b','c','d' but fails for 'a' (this is intensional - it's a unit test).

How do I correctly modify the above example to pass the test?

Upvotes: 0

Views: 119

Answers (3)

Hoopdady
Hoopdady

Reputation: 2356

If I understand your question correctly, you can accomplish it with this:

new_dict = {k:v[len(v)>1:] for k,v in old_dict.items()}

v[len(v)>1] will return the key if it is only 1 character, and it will strip off the leading character if it is more than one character

I'm not sure what you are trying to accomplish with if item.startswith('1') is a qualifier for your list comprehension but if you need it you can add it back on. May need to make it v.startswith('1') though.

Upvotes: 0

Marcin
Marcin

Reputation: 49856

The nature of a comprehension is that it builds a new object iteratively, so you if you want every key in the original object old_dict to have a corresponding key in new_dict, you simply have to process every key.

Also, you say "I need to slice the leading character off the keys a dictionary", but the code you give slices the leading characters off the values. I assume you mean values. I suggest the following:

new_dict = {key:(value[:1] if len(value) > 1 else value) for key,value in old_dict.iteritems()}

Apart from using sequence assignment to make the iteration a bit clearer, I've used the if expression (equivalent to ternary operator in c-like languages) to incorporate the condition.

I've also dropped your original if clause, because I don't understand you to want to skip values starting with '1'.

Upvotes: 1

dutt
dutt

Reputation: 8209

I'm not sure which variable is where but you could do something along these lines.

new_dict = { item[0]:item[1][1] if len(item[1]) > 1 else item[0]:item[1] for item in old_dict if item.startswith('1') }

Upvotes: 1

Related Questions