【问题标题】:Selecting specific int values from list and changing them从列表中选择特定的 int 值并更改它们
【发布时间】:2016-02-28 13:19:15
【问题描述】:

我一直在玩 Python,遇到了麻省理工学院的一项任务,即创建编码消息(Julius Cesar 代码,例如,您将消息中的 ABCD 字母更改为 CDEF)。这是我想出的:

Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))

listPhrase = list(Phrase)
listLenght = len(listPhrase)

ascii = []
for ch in listPhrase:
  ascii.append(ord(ch))
print (ascii)

asciiCoded = []
for i in ascii:
    asciiCoded.append(i+shiftValue)
print (asciiCoded)

phraseCoded = []
for i in asciiCoded:
    phraseCoded.append(chr(i))
print (phraseCoded)

stringCoded = ''.join(phraseCoded)
print (stringCoded)

代码有效,但我必须实现不移动消息中空格和特殊符号的 ascii 值。

所以我的想法是在 range(65,90) 和 range(97,122) 范围内的列表中选择值并更改它们,而我不更改任何其他值。但是我该怎么做呢?

【问题讨论】:

标签: python python-3.x


【解决方案1】:

如果你想使用那个巨大的代码 :) 来做这么简单的事情,那么你可以像这样进行检查:

asciiCoded = []
for i in ascii:
    if 65 <= i <= 90 or 97 <= i <= 122:  # only letters get changed
        asciiCoded.append(i+shiftValue)
    else:
        asciiCoded.append(i)

但是你知道吗,python 可以在一行中使用list comprehension 完成所有这些工作。观看:

Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))

# encoding to cypher, in single line
stringCoded = ''.join(chr(ord(c)+shiftValue) if c.isalpha() else c for c in Phrase)

print(stringCoded)

一点解释:列表推导归结为这个 for 循环,它更容易理解。抓到什么了? :)

temp_list = []
for c in Phrase:
    if c.isalpha():
        # shift if the c is alphabet
        temp_list.append(chr(ord(c)+shiftValue))
    else:
        # no shift if c is no alphabet
        temp_list.append(c)

# join the list to form a string
stringCoded = ''.join(temp_list)

【讨论】:

  • 如果您不想让“幻数”四处飘荡,659097122ord('A')ord('Z')、@987654333 @ 和 ord('z')
  • 我知道,但从 OP 看来,猜测 OP 也知道这一点似乎是合理的。所以使用这些神奇的数字没有害处。请注意,两个 OP 的含义不同。 :)
  • Shadowfax 你能告诉我,或者链接我解释,那些双括号是做什么的?例如这里的示例: stringCoded = ''.join(temp_list)
  • @RadekE 看看这个str.jointhis。希望这会有所帮助。
【解决方案2】:

使用字符串模块中的 maketrans 方法要容易得多:

>>import string
>>
>>caesar = string.maketrans('ABCD', 'CDEF')
>>
>>s = 'CAD BA'
>>
>>print s
>>print s.translate(caesar)
CAD BA
ECF DC

编辑:这是用于 Python 2.7

使用 3.5 就可以了

caesar = str.maketrans('ABCD', 'CDEF')

还有一个返回映射的简单函数。

>>> def encrypt(shift):
...     alphabet = string.ascii_uppercase
...     move = (len(alphabet) + shift) % len(alphabet)
...     map_to = alphabet[move:] + alphabet[:move]
...     return str.maketrans(alphabet, map_to)
>>> "ABC".translate(encrypt(4))
'EFG'

此函数使用模加法来构造加密的凯撒字符串。

【讨论】:

  • OP 用 python 3.x 标记。你的适用于 python 2.x。并且它没有考虑作为用户输入的 shiftValue。如果要处理 A-Z 和 a-z 将非常笨拙。
  • 谢谢Shadowfax。显然我是一个懒惰的读者;-) 我更新了我的评论以反映您的评论。
【解决方案3】:
asciiCoded = []
final_ascii = ""
for i in ascii:
    final_ascii = i+shiftValue #add shiftValue to ascii value of character
    if final_ascii in range(65,91) or final_ascii in range(97,123): #Condition to skip the special characters
        asciiCoded.append(final_ascii)
    else: 
        asciiCoded.append(i)
print (asciiCoded)

【讨论】:

  • 对于每种情况,Zz 都被遗漏了。去图吧。
  • range() 不包括端点。你想要range(65, 91)range(97, 123)
  • 这只是因为如果你尝试为 Z/z 添加移位值,即它的 90 + 任何移位或 122+ 任何移位值都会将它带到其他非字母字符 > 91 或 122
  • True Shadowfax 必须 b +1
猜你喜欢
  • 1970-01-01
  • 2019-12-02
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
相关资源
最近更新 更多