【问题标题】:Python 3: Generate not all permutations, but all non-repetitive combinations of length r?Python 3:不是生成所有排列,而是生成长度为 r 的所有非重复组合?
【发布时间】:2012-02-12 18:49:24
【问题描述】:

我正在尝试生成长度为 r 的 Vigenere 密码密钥的可延迟迭代集合。我知道itertoolspermutations() 方法。但是,这会生成诸如ABCDABCEABCF 之类的密钥,但它永远不会执行诸如AABC 之类的操作。

所以基本上,我需要不重复的元组或字符串(也就是说,可以将重复的键切成两半以获得相同的两半),但可以包含重复的字符。很好的例子:AABABA,而不是AABAAB

如何创建这样的集合,它不会生成这样的密钥,并且会延迟迭代,以便在我想探索超过 3 个字符的密钥时不会炸毁我的 RAM?

【问题讨论】:

  • 你的意思是“不能把钥匙切成两半得到两个相同的一半”?
  • 也许听起来模棱两可,但我的意思是说“重复”意味着你可以做这样的事情。
  • 这不是模棱两可,是矛盾的。首先你说不重复(所以AABAAB 不会工作),然后你说你可以把钥匙切成两半并得到两个相同的两半(所以AABAAB 工作)。您的示例支持前者。只是要求澄清。
  • 我认为 OP 意味着 repetitive == can cut into equal halves 并且字符串不应重复,如示例所示。
  • 我会改变它,在这种情况下。

标签: python cryptography iteration lazy-evaluation vigenere


【解决方案1】:

听起来您想使用itertools.combinations_with_replacement()。最重要的是,您可以围绕它编写一个生成器来过滤掉您不想要的那些。

http://docs.python.org/library/itertools.html#itertools.combinations_with_replacement

【讨论】:

  • +1。非常好,虽然我经常使用itertools,但从不需要它。似乎正是@agarett 想要的。
  • 我知道它是如何创建所有组合的,但我不知道如何编写这样的生成器。在遍历键时,我可以检查前半部分是否等于后半部分,但如果可以神奇地避免这种情况,我更愿意这样做。
【解决方案2】:
("".join(s) for s in product(alphabet, repeat=n) if s[:n//2]!=s[n//2:])

编辑:感谢@PetrViktorin

【讨论】:

  • 您可以改用nlen(s)。此外,使用// 运算符进行整数除法。
  • 我收到了TypeError: 'int' object is not iterable
  • alphabet 你认为是什么?它应该是一个可迭代的,例如字符串或字符列表。
  • 我使用的是string.ascii_uppercase,我很确定这是一个可迭代的。
  • 它对我有用。您的其中一个名称未正确定义:alphabet 不是可迭代的或 product 不是 itertools.product
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多