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)