Hello, I'm currently in school for computer science, graduating next year and I've been browsing some of the leetcode problems. I was a bit disheartened as when I read some of the answers it looks like I'm reading a foreign language. I've been trying to give myself simple problems so I can get comfortable converting different types of data to dictionaries, I still have a few classes to take but have not really worked with them. What I've been trying to do is convert the string '1a2a3c' into a dictionary {1 : a, 2 : b, 3 : c} using a for a loop. Eventually, I want to create a function that does this. So far I've only been able to come up with this
s = '1a2b3c'
keys = []
keys[:0] = s
dic = {}
for i in keys:
if (keys.index(i) % 2) == 0:
dic[keys[i]] = keys[i + 1]
But when I try to run this I get the error
Error:
Traceback (most recent call last):
File "<string>", line 7, in <module>
TypeError: can only concatenate str (not "int") to str
Does anyone know what I'm doing wrong?
Here is one way
string = '1a2b3c4d'
l1 = []
l2 = []
for char in string:
l1.append(char) if char.isnumeric() else l2.append(char)
mydict = dict(zip(l1,l2))
print(mydict)
Your problem is you are trying to use a str as a number. You cannot "a" % 2. You can't even "1" % 2. If you want to index the list you need to loop through index values, not list items. You can write your code like this:
keys = list('1a2b3c')
dic = {}
for i in range(len(keys)):
if (i % 2) == 0:
dic[keys[i]] = keys[i + 1]
print(dic)
Or better yet:
keys = list('1a2b3c')
dic = {}
for i in range(0, len(keys), 2):
dic[keys[i]] = keys[i + 1]
print(dic)
Or even better:
keys = list('1a2b3c')
dic = {keys[i]:keys[i+1] for i in range(0, len(keys), 2)}
print(dic)
I would use zip and slices to make (key, value) tuples. The dict() function can use these to make a dictionary
s = "1a2b3c"
sdict = dict(zip(s[::2], s[1::2]))
print(sdict)
s[::2] gets every second character starting at zero ('1', '2', '3').
s[1::2] gets every second character starting at one ('a', 'b', 'c')
zip(s[::2], s[1::2]) generates tuples ('1', 'a'), ('2', 'b'), ('3', 'c')
The dict() function converts the sequence of key, value tuples into a dictionary.
mystring = '1a2b3c4d'
mydict = {mystring[i-1]:mystring[i] for i in range(1, len(mystring), 2)}
from more_itertools import chunked, sliced
spam = '1a2b3c4d'
# without using more_itertools
print(dict(zip(spam[::2], spam[1::2])))
# using more_itertools
print(dict(chunked(spam, 2)))
print(dict(sliced(spam, 2, strict=True)))
Output:
{'1': 'a', '2': 'b', '3': 'c', '4': 'd'}
{'1': 'a', '2': 'b', '3': 'c', '4': 'd'}
{'1': 'a', '2': 'b', '3': 'c', '4': 'd'}
Another way could be using built-in
zip for clustering a data serie into specified length groups (in this case two) and feed it to built in dict constructor.
From documentation:
Quote:Tips and tricks:
The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n, strict=True). This repeats the same iterator n times so that each output tuple has the result of n calls to the iterator. This has the effect of dividing the input into n-length chunks.
>>> s = '1a2b3c4d'
>>> n = 2
>>> dict(zip(*[iter(s)]*n, strict=True))
{'1': 'a', '2': 'b', '3': 'c', '4': 'd'}
Using the same iterator to extract both items for each tuple is brilliant. It is not immediately obvious though. It took a minute for me to understand how it worked,
def todict(kvstring):
i = iter(kvstring)
return dict(zip(i, i))