1

I'm new to python and trying to write a program to compare strings; specifically the characters in sequence in each string and the decimal ASCII values of these characters.

For example, I have string 1 'abcd1234' and string 2 'bcde2345'

In ASCII decimal this would be 97,99,101,103,53,55,57,59 and 97,98,99,100,49,50,51,52

I want to find the difference in the decimal number of each character in sequence and be able to apply this decimal difference to a new string to shift its characters.

So far I have following:

str1 = 'abcd1234'
str2 = 'bcde2345'
str3 = '7:69h5i>'
tem = {55,58,54,57,104,53,105,62}  # just a test to see if I could use a set

print(str1)
for i in str1:
    print(ord(i))

print('\n')

print(str2)
for i in str2:
    print(ord(i))

print('\n')

print(str3)
for i in str3:
    print(ord(i))


print('\n')

i = 0

print(tem)
for i in tem:
    print(chr(i))

I thought I could do it using a set but the characters are re-arranged somehow when I do print of them.
I'm sure there's an easy way of achieving what I'm after!

Aimondy
  • 31
  • 4
  • I’m not sure what you want to achieve here and where your exact problem is. Can you be a bit more specific? Which part of the question do you have problems with (calculating the difference for each character? making a string out of the differences?); Also, what do you do if the difference becomes negative? – Jonas Schäfer Aug 02 '15 at 10:45
  • Regular Python sets don't preserve order probably because they are hashed under the hood like java sets. However, there is an ordered set class for Python. See https://pypi.python.org/pypi/ordered-set/ and http://orderedset.readthedocs.org/en/latest/. Ordered sets should be incorporated into Python collections since they can be useful and other major languages have them. –  Aug 02 '15 at 10:49
  • Sorry the root problem is; I have an initial string and a 2nd string that is a shifted version of the first string. The shift occurs on the decimal ascii values of each character and can be a negative value. Each character can have a different shift value to the rest. I want to find the shift value for each character then use these shift values to alter a 3rd string. – Aimondy Aug 02 '15 at 10:51
  • Why did you think a `set` would be appropriate? It looks like you want to perform simple mappings against the three strings, which is often done using either list comprehensions or generator expressions (for lazy evaluation). If I'm understanding your problem correctly, I would try something like: https://ideone.com/wIgPXK ... – johnsyweb Aug 02 '15 at 10:56
  • I found it easy enough to print each char with for loops but don't know how to achieve the comparisons and alteration of 3rd string inside a loop – Aimondy Aug 02 '15 at 10:58
  • 1
    Thank you heaps Johnsyweb that example nailed it and was much more elegant than what I would have ended up with :) – Aimondy Aug 02 '15 at 11:08

2 Answers2

0

A set is by definition unordered.

A set object is an unordered collection of distinct hashable objects

See this question about ordered sets in Python: Does Python have an ordered set?


As for the shifting: If I understand your question correctly the following code should do more or less what you need:

str1 = 'abcd1234'
str2 = 'bcde2345'
str3 = '7:69h5i>'

assert len(str1) == len(str2) == len(str3)

str3 = list(str3)  # to be able to access the characters we need to turn the str into list

for idx in range(len(str1)):
    shift_val = ord(str2[idx]) - ord(str1[idx])  # get the diff
    print(shift_val)
    str3[idx] = chr(ord(str3[idx]) + shift_val)  # apply the diff 

print(''.join(str3))
b3000
  • 1,547
  • 1
  • 15
  • 27
  • "to be able to access the characters we need to turn the str into list" Why? – johnsyweb Aug 02 '15 at 11:06
  • It is needed for the assignment `str3[idx] = chr(ord(str3[idx]) + shift_val)` since (if not turned into list) `'str' object does not support item assignment` Another way would of course be just to create a new str – b3000 Aug 02 '15 at 11:09
  • Ah I see what you mean, I edited the code. Now only `str3` is turned into a list. – b3000 Aug 02 '15 at 11:13
0

It looks like you want to perform simple mappings against the three strings, which is often done using either list comprehensions or generator expressions (for lazy evaluation).

If I'm (@johnsyweb is) understanding your problem correctly, I would try something like:

#!/usr/bin/env python3
str1 = 'abcd1234'
str2 = 'bcde2345'
str3 = '7:69h5i>'

ord1 = (ord(c) for c in str1)
ord2 = (ord(c) for c in str2)
ord3 = (ord(c) for c in str3)

diffs = (x - y for x,y in zip(ord1, ord2))

result = (chr(x + y) for x,y in zip(diffs, ord3))

print(''.join(result))

See it run!

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
Aimondy
  • 31
  • 4