Issue
I am a beginner in Python and I just encounter some strange behaviour about dicts when I try to do the Advent of Code (AoC) 2021_Dec_01 question.
The AoC question is like this: A txt file contains the following element is given
199
200
208
210
200
207
240
269
260
263
If the element is greater than the previous one, set to increased. If it is smaller than the previous one set decreased. So it should become:
199 (N/A - no previous measurement)
200 (increased)
208 (increased)
210 (increased)
200 (decreased)
207 (increased)
240 (increased)
269 (increased)
260 (decreased)
263 (increased)
I try to convert the above file into a list, than create an dictionary from it:
try:
with open("test.txt", "r") as depths:
# Create a list for depths and clear "\n after each words"
depths_list = []
for x in depths:
depths_list.append(x.rstrip())
print(depths_list)
# depths_list = ['199', '200', '208', '210', '200', '207', '240', '269', '260', '263']
# Create a dict to store {depth : increased/decreased} data
i = 0
depths_dict = {}
for depth in depths_list:
if i == 0:
depths_dict[depth] = "(N/A - no previous measurement)"
elif depth > depths_list[i-1]:
depths_dict[depth] = "(increased)"
elif depth < depths_list[i-1]:
depths_dict[depth] = "(decreased)"
i+=1
print(depths_dict) #Add this for debugging
except Exception as e:
print(f"ERROR FOUND: {e}")
I added a print(depths_dict)
for debugging, the output surprises me and I am quite confusing about what is happening.
below is the output:
{'199': '(N/A - no previous measurement', '200': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(increased)', '208': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(increased)', '208': '(increased)', '210': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(decreased)', '208': '(increased)', '210': '(increased)', '207': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(decreased)', '208': '(increased)', '210': '(increased)', '207': '(increased)', '240': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(decreased)', '208': '(increased)', '210': '(increased)', '207': '(increased)', '240': '(increased)', '269': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(decreased)', '208': '(increased)', '210': '(increased)', '207': '(increased)', '240': '(increased)', '269': '(increased)', '260': '(decreased)', '263': '(increased)'}
{'199': '(N/A - no previous measurement', '200': '(decreased)', '208': '(increased)', '210': '(increased)', '207': '(increased)', '240': '(increased)', '269': '(increased)', '260': '(decreased)', '263': '(increased)'}
As shown above, the second element in the dict {200:(increased)}
suddenly changed from increased to decrease after the 3rd iteration.
What is happening there? How come the value of depths_dict[200]
is changed which I haven't done anything like depths_dict[200] = sth
?
Solution
The problem you are facing is due to the fact you are reassigning new values to existing keys. You will need to change the way you process your data. Here a suggestion:
# picking up your parse data:
l = ['199', '200', '208', '210', '200', '207', '240', '269', '260', '263']
trend = ['NA'] # a container to store trends, start with no change ('NA')
# iterate through your data
for i in range(1, len(l)): # start at the second element
if int(l[i]) - int(l[i - 1]) > 0:
trend.append('(increased)')
elif int(l[i]) - int(l[i - 1]) < 0:
trend.append('(decreased)')
else:
trend.append('(no change)')
# maybe you want a dictionary of the positions/values and the trend now?
d = {(i, val): trend_val for (i, val), trend_val in zip(enumerate(l), trend)}
d
{(0, '199'): 'NA',
(1, '200'): '(increased)',
(2, '208'): '(increased)',
(3, '210'): '(increased)',
(4, '200'): '(decreased)',
(5, '207'): '(increased)',
(6, '240'): '(increased)',
(7, '269'): '(increased)',
(8, '260'): '(decreased)',
(9, '263'): '(increased)'}
But yet a cleaner way to do this is to use pandas:
l = ['199', '200', '208', '210', '200', '207', '240', '269', '260', '263']
l = [int(x) for x in l]
s = pd.Series(l)
def decision(x):
if x > 0:
return '(increased)'
if x < 0:
return '(decreased)'
return '(no change)'
data = s.diff().apply(lambda x: decision(x))
data
0 (no change)
1 (increased)
2 (increased)
3 (increased)
4 (decreased)
5 (increased)
6 (increased)
7 (increased)
8 (decreased)
9 (increased)
dtype: object
From here on you could build anything like via data.to_dict()
Answered By - deponovo
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.