Okay so i did read this question few hours ago on phone and started working out an answer on paper, having the performance tag in mind.
So here it is:
untouched lines:
items = {1:'one', 2:'two', 3:'three'}
text = "foo" # This variable may change on runtime. Added to allow the execution
number = 1 # This variable may change on runtime. Added to allow the execution
first changes made here. Your Code does set sring and overwrtes it if items[numer]
equals string "two". I dont like those inline if elses in long lines so i will take more space then other answers but think this is more readable.
if items[number] == "two":
string = text
else:
string = "{}{} trailing".format(text, items[number])
next line is untouched again with:
string = [ord(x) for x in string]
and now my performance-part comes into play. To understand i will explain your algorith and how i rearanged it. You zip the String starting with the second element and itself. This resolves to [[string[1], string[0]], [string[2], string[1]], ... , [string[last element], string[last element -1]]]
.
This is a list with len(string) -1 elements.
So we will memorize strings length
string_len = len(string)
We will also memorize if the number of zip-lists elements would be even or odd. In case string has an odd number of elements zip-list would have an even number and if strings number of elements would be even zip-lists had been odd.
odd = (string_len -1) % 2
We will also do the initial setup for checksum as is:
checksum = string[0]
Iterating over iterator there are 2 cases: the iteration is odd
if counter % 2:
checksum += x
checksum += 2 * y
or its even
else:
checksum += x * y
There are two things unnecessary in my opinion. First is creating the zip-list since you can access every element by index. Element x is string[iteration+1]
, y is string[iteration]
. Since counter is successively even and odd we can also say that for two iterations we will once do
checksum += x * y
in case our iteration-counter is even and
checksum += x
checksum += 2 * y
in case its not even.
Or we will just allways do 2 iterations in one step and do both operations like:
for i in range(0, string_len -1 -odd, 2):
checksum += string[i] * string[i + 1] # counter % 2 := false checksum += x * y
checksum += string[i + 2] # counter % 2 := true checksum += x
checksum += 2 * string[i + 1] # counter % 2 := true checksum += 2 * y
Now why we did memorize if zip-lists number of elements would had been odd or even:
We allways made 2 operations but this wont work for an odd number of operations. So we will check once with an if what to do:
if odd:
checksum += string[i] * string[i + 1]
Anything else as is:
checksum %= 0x10000
print("Checksum:", checksum)
it might be recommendable to save the modulo in another place like other answers mention.
Entire Code looks like this:
items = {1:'one', 2:'two', 3:'three'}
text = "foo" # This variable may change on runtime. Added to allow the execution
number = 1 # This variable may change on runtime. Added to allow the execution
if items[number] == "two":
string = text
else:
string = str.format("{:s}{:s} trailing", text, items[number])
string = [ord(x) for x in string]
string_len = len(string)
odd = (string_len -1) % 2
checksum = string[0]
for i in range(0, string_len -1 -odd, 2):
checksum += string[i] * string[i + 1] # counter % 2 := false checksum += x * y
checksum += string[i + 2] # counter % 2 := true checksum += x
checksum += 2 * string[i + 1] # counter % 2 := true checksum += 2 * y
if odd:
checksum += string[i] * string[i + 1]
checksum %= 0x10000
print("Checksum:", checksum)
str_a
andstr_b
to some strings ... \$\endgroup\$