Python列表理解 - 访问最后创建的元素?
是否可以访问在列表理解中生成的前一个元素。Python列表理解 - 访问最后创建的元素?
我正在做一些玩具加密的东西。将密钥作为任意大的整数,初始化值和元素列表作为要加密的消息。我需要用先前的加密元素和密钥对每个元素进行异或。下面的循环会做。
previous = initialization_value
cipher = []
for element in message:
previous = element^previous^key
cipher.append(previous)
我觉得它应该有可能变成一个列表理解,但我不完全知道如何处理这两个初始值或访问产生的前值。 是否有可能,如果是的话,理解是什么?
没有一个好的Pythonic方法来做到这一点与列表理解。考虑列表解析的最佳方式是替代map
和filter
。换句话说,你会使用一个列表理解时,你需要采取的列表,并
使用它的元素作为输入一些表达(如平方元素)
删除某些内容的基于一些条件
这些事情的共同之处在于它们每次只能查看单个列表元素。这是一个很好的经验法则;即使你理论上可以将你所显示的代码编写成一个列表理解,但它会是尴尬和不合理的。
你可以使用一个辅助对象来存储所有的内部状态,而遍历序列:
class Encryption:
def __init__(self, key, init_value):
self.key = key
self.previous = init_value
def next(self, element):
self.previous = element^self.previous^self.key
return self.previous
enc = Encryption(...)
cipher = [enc.next(e) for e in message]
话虽这么说,以前加密的元素到XOR不会使你的算法任何更难而不是仅仅用关键字敲击每个元素。攻击者可以使用先前的加密字符对密文中的任何字符进行异或,从而抵消在加密过程中完成的异或。
您可以使用reduce()来完成此操作。这不是列表理解,但它是功能风格的方法:
cipher = []
def f(previous, element):
previous = element^previous^key
cipher.append(previous)
return previous
reduce(f, message, initialization_value)
它在这种情况下没有任何比普通循环更漂亮。
使用前检查性能减少;它通常会导致显着低效的结构。 – 2009-04-27 20:30:55
'for循环'版本* *更清洁,因此只将这个答案看作是“理论上可能做不到的事情”。 – 2009-04-28 07:12:35
作为发电机:
def cypher(message, key, seed):
for element in message:
seed = element^seed^key
yield seed
list(cypher(message, key, initial_seed))
即使不是OP要求的,我也喜欢这个解决方案。 – MaLiN2223 2016-12-13 10:46:00
+1:这就是为什么我们仍然有for语句 - 用于酷似这个问题的情况。 – 2009-04-27 19:48:44