Home > Mobile >  Split list with both negative and positive number into a dictionary
Split list with both negative and positive number into a dictionary

Time:12-29

I am trying to split a list of strings into a dict some of these strings end up been duplicate keys after they are split, my end goal is to split the list then sum up the values for each key. I have the following code that works, however I receive a ValueError: too many values to unpack (expected 2). when the list contains a negative integer. How would I go about fixing this.

v=["a:1", "b:3", "c:5","c:3"]
list_of_str  = list(map(lambda elem: elem.replace(":", ''), v))
list_of_str

from collections import defaultdict
my_dict = defaultdict(list)
for k, v in list_of_str:
    my_dict[k].append(v)
my_dict

defaultdict(list, {'a': ['1'], 'b': ['3'], 'c': ['5', '3']})

Result with negative value in the list

v=["a:1", "b:3", "c:5","c:-3"]
list_of_str  = list(map(lambda elem: elem.replace(":", ''), v))
list_of_str
​
from collections import defaultdict
my_dict = defaultdict(list)
for k, v in list_of_str:
    my_dict[k].append(v)
my_dict

ValueError   Traceback (most recent call last)
<ipython-input-48-7a8d435becbb> in <module>
      5 from collections import defaultdict
      6 my_dict = defaultdict(list)
----> 7 for k, v in list_of_str:
      8     my_dict[k].append(v)
      9 my_dict

ValueError: too many values to unpack (expected 2)

The result I am going for:
defaultdict(list, {'a': ['1'], 'b': ['3'], 'c': ['5', '3']})
a:1,b:3,c:8

CodePudding user response:

When you loop on your list of strings and try to extract two values each string is treated as an interable with each character being a value of the iterable.

So when you're doing:

k, v = 'b3'
# k = 'b', v = '3'

But when you're doing:

k, v = 'c-3'
# k = 'c', 'v' = '-'

In the above example the string still has a character left that's why you get ValueError: too many values to unpack (expected 2) the code expected 2 values but you provided 3.

You could do:

from collections import defaultdict

v = ['a:1', 'b:3', 'c:5', 'c:3', 'd:-4']

my_dict = defaultdict(list)
for str in v:
    key, value = str.split(':')
    my_dict[key].append(value)

CodePudding user response:

You can go with:

from collections import defaultdict

v = ["a:1", "b:3", "c:5", "c:-3"]
list_of_str = list(map(lambda elem: elem, v))
print(list_of_str)

my_dict = defaultdict(list)

for item in list_of_str:
    k, v = item.split(":")
    my_dict[k].append(v)
print(my_dict)

CodePudding user response:

In the loop where you construct the dictionary you are iterating through elements of list_of_str. Each of these elements is a string, and by doing for k, v in ... you're asking for the first two characters of that string.

It so happens that in your first example each string ends up with just two characters. However when you have a negative number, you suddenly have three values instead, and you're asking for only two (i.e. you actually have 'c', '-', and '3').

You can simplify your problem using something more memorable instead of an empty string when substituting ':':

list_of_str  = list(map(lambda elem: elem.replace(":", ','), v))

So that you can than split whatever happens to be the key-value pair in the loop,

for el in list_of_str:
   key, value = el.split(',')
   my_dict[key].append(value)   

This, however, is redundant and a better way would be to skip the replace altogether and split by ':' right in the loop,

for el in v:
    key, value = el.split(':')
    my_dict[key].append(value)
  • Related