【问题标题】:python 2.7 replacing a raw_input string with a value from a dictionarypython 2.7 用字典中的值替换 raw_input 字符串
【发布时间】:2016-08-19 02:01:54
【问题描述】:

我对编程非常陌生(6 周,在网上自学了“codecademy”和“python the hard way”)。我决定是时候开始尝试在没有方向的情况下编写代码了,我的第二个项目碰壁了。

我正在尝试制作一个“秘密编码器”,它采用 raw_input 字符串并将其中的每个字母替换为字母表中的下一个字母。以我非常有限的知识,我认为字典应该是要走的路。在“一点”谷歌搜索帮助下,我写了这个:

alpha = {"a" : "b", "b" : "c", "c" : "d", "d" : "e", "e" : "f",  "f" : "g","g" : "h"
         , "h" : "i", "i" : "j", "j" : "k", "k" : "l", "l" : "m","m" : "n", "n" : "o"
         , "o" : "p", "p" : "q", "q" : "r", "r" : "s","s" : "t", "t" : "u", "u" : "v"
         , "v" : "w", "w" : "x", "x" : "y", "y" : "z", "z" : "a"}

entry = raw_input("Please write a sentence you want to encode: ")

def encode(entry, letters):
    for k, v in letters.iteritems():
        if k in alpha:
            entry = entry.replace(k, v)
    return entry
print encode(entry, alpha)

我遇到的问题是字符串中只有一半的字母被字典中的正确值替换。当“a”应打印为“b”且“b”应打印为“c”时,“a”和“b”都将打印为“c”,依此类推。

illustration

我完全迷失的地方是,当我用数字替换字典中的每个值时,它工作得很好。

illustration bis

这就是它的要点,我真的不明白我的代码有什么问题。

提前感谢您的帮助。

PS:这是我在 * 上的第一篇文章,希望我能按照我应该的方式做所有事情。

编辑:由于我还不能提供声誉,我将在这里感谢大家的有用回答。我现在可以更清楚地看到我的错误在哪里,我将利用此处提供的信息来修复我的代码并努力正确理解它。我也可以看到解决这类问题有更多合乎逻辑和直接的方法。功能对我来说仍然有点模糊,但我想这么早是正常的。

【问题讨论】:

  • 你需要循环输入,而不是字母,并用 '' 加入每个字符
  • 想象一下这种情况......你的字符串中有一个a,你循环并将所有a更改为bs,但是随后,你循环并更改所有bs 到cs(其中可以包括您已更改为bs 的as 等...)
  • :D 伙计,我喜欢你的热情。 Python 既方便又强大,因此类似的练习将是使用实际的加密解决方案来加密您的消息 - 亲眼看看使用 Python *.com/questions/30056762/… 有多简单 :)
  • 正如许多其他人所说,您可以像 for e in entry: result += letters[e]... 那样进行迭代,python 将为您完成剩下的工作。值得你学习的东西(越早越好)是你不应该修改你正在迭代的对象,这将在未来为你省去很多麻烦。

标签: python python-2.7 function dictionary raw-input


【解决方案1】:

Xetnus 是正确的,您需要遍历条目变量而不是字母。也许是这样的

def encode(entry, letters):
    new_entry = ''
    for letter in entry:
        if letter in letters:
            new_entry += letters[letter]
    return new_entry
print encode(entry, alpha)

【讨论】:

    【解决方案2】:

    问题在于,由于您迭代的是字典而不是字符串,因此您可能会多次替换原始字符。例如,如果iteritemsa, b 的顺序返回键,则给定输入'ab' 第一个替换将导致'bb',第二个替换将导致'cc'。请注意,由于字典是无序集合,因此返回项目的顺序是随机的。

    您可以通过使用generator expression 迭代源字符串并使用join 创建结果来解决此问题:

    def encode(entry, letters):
        return ''.join(letters.get(c, c) for c in entry)
    

    上面的例子是调用get而不是使用索引运算符来处理alpha在源字符串中不包含字母的情况。 get 和索引运算符之间的区别在于 get 采用第二个参数,该参数是默认值,如果该键不存在,将返回该参数。在上面的例子中,默认值是字符本身。

    【讨论】:

    • 非常干净的解决方案(我赞成),因为 OP 是初学者,提供更广泛的解释会很酷。就像 get() 方法以及它如何从字母中选择值或使用提供的键作为默认值以防找不到项目。
    【解决方案3】:

    字典没有排序,因此您要替换一些字母('a' -> 'b'),而其他的则被跳过。

    为了您的启迪,您正在做的事情称为rot(轮换)。最知名的是rot13

    刚开始时自己编写会很有帮助,但是有一个非常酷的标准库函数 string.maketrans 可以做到这一点!

    【讨论】:

      【解决方案4】:

      其他人指出了如何使用字典作为查找正确地执行此操作。但是,您也可以使用 str.translate 方法,避免查找和重建字符串。

      import string
      
      trans = string.maketrans(
          'abcdefghijklmnopqrstuvwxyz', # from...
          'bcdefghijklmnopqrstuvwxyza' # to
      )
      
      print raw_input('Please enter something to encode: ').translate(trans)
      

      【讨论】:

      • 这是一种非常优雅和简单的方式来做我想做的事情,我肯定会使用它,因为我已经看到如何让我的代码用它对字符串进行更复杂的操作。在其他答案中提供的帮助下,我将努力使我的函数执行我想要的操作,然后,一旦我能够正确编码,我将切换到使用 str.translate 方法,因为它很简单。感谢您的建议。
      【解决方案5】:
      def encode(entry, letters):
          for k, v in letters.iteritems():
              if k in alpha:
                  entry = entry.replace(k, v)
          return entry
      print encode(entry, alpha)
      

      在您的打印函数中调用encode(entry, alpha),您将encode() 函数传递给alpha 字典作为函数中的letters 变量。然后,您使用迭代器循环遍历letters 变量(即alpha 字典)。然后,您的 if 语句检查 k(您刚刚从 letters 变量,即 alpha 字典中获得)是否在 alpha 字典中,当然是。

      您需要这样做:

      for k, v in letters.iteritems():
          if k in entry:
              entry = entry.replace(k, v)
      

      【讨论】:

        最近更新 更多