【问题标题】:Align through two different strings of different lengths?通过两个不同长度的不同字符串对齐?
【发布时间】:2016-01-17 02:16:45
【问题描述】:

如果我有两个字符串,例如:

plaintext = "hello"
key = "hi"

如何在不超出范围的情况下将字母(或空格和标点符号等其他字符)对齐?到目前为止,我正在这样做,但我一直遇到字符串超出索引错误。

encryption = ""
for index in range(len(plaintext)):
    if plaintext[index] in alphabet:
        encryption += vigenere_encrypt(plaintext[index], key[index])
    if plaintext[index] not in alphabet:
        encryption += plaintext[index]
return encryption

我实际上是在尝试使我的密钥与明文的长度相匹配,所以"hi" --> "hihih" 它与“hello”的长度相同,因此它可以同时循环遍历两者而不会遇到超出范围的错误

【问题讨论】:

  • 您到底想达到什么目的?这两个字符串的预期输出是什么?
  • 你为什么要建立索引以及 vigenere_encrypt 是什么?
  • 我实际上是在尝试使我的密钥与纯文本的长度相匹配,因此“hi”应该变成“hihih”,它与“hello”的长度相同
  • 我有一种感觉 str.translate 会做很多你的代码正在做的事情

标签: python string loops


【解决方案1】:

如果您希望较短的 key 字符串环绕,请在索引时使用模数:

encryption += vigenere_encrypt(plaintext[index], key[index % len(key)])

另一种方法是使用itertools.cycle 来创建一个迭代器,当您对其进行迭代时,它会永远重复来自key 的值。然后,您可以使用zip 将其与plaintext 结合起来(一种比使用索引更Pythonic 的组合两个序列的方式)。这是一个在生成器表达式中进行整个加密的版本:

import itertools

encryption = "".join(vigenere_encrypt(plain_char, key_char)
                         if plain_char in alphabet else plain_char
                     for plain_char, key_char in zip(plaintext, itertools.cycle(key))

【讨论】:

  • 带有连接的生成器表达式实际上更慢,而且空间效率更高,因为无论如何你最终都会得到一个列表
  • 我的意思是str.join 可能比在字符串上重复使用+= 更有效,因为重复复制早期字符(在幼稚的实现中)会使用O(N**2) 时间.因为初学者用+=扩展字符串是很常见的事情,所以CPython在str.__add__中有一些特殊的检查,如果没有其他引用,它实际上会重用左手参数而不复制它,但我认为这是一个坏主意依靠这种优化。
猜你喜欢
  • 1970-01-01
  • 2022-11-16
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 2017-03-12
  • 1970-01-01
相关资源
最近更新 更多