我正在尝试为模数11编写代码但是我没能使它更像python。
截至目前,我正在使用一个重量并增加它,检查它何时到达一个数字,然后将其设置为原始值。
假设我有一个数字列表
1..20
我希望将它们乘以2,3,4,5,6,7,8,9,2,3,4,etc
,以便每个索引乘以一个递增的数字。
1x2,2x3,3x4,4x5,5x6,6x7,7x8,8x9,9x2,10x3等。
有优雅的方法吗?
不雅的方式:
def mod11(list, max_weight=9):
sum = 0
weight = 2
for item in reversed(list):
sum += item * weight
weight += 1
if weight > max_weight:
weight = 2
mod = 11 - sum % 11
if mod > 9:
return 0
else:
return mod
答案 0 :(得分:2)
您可以使用当前索引来确定乘数:
>>> [(index % 8 + 2) * item for index, item in enumerate(range(1, 21))]
[2, 6, 12, 20, 30, 42, 56, 72, 18, 30, 44, 60, 78, 98, 120, 144, 34, 54, 76, 100]
#^ resets ^ resets ^
或者,你可以"cycle"乘法器序列并用输入序列压缩:
>>> from itertools import cycle
>>> [x * y for x, y in zip(range(1, 21), cycle(range(2, 10)))]
[2, 6, 12, 20, 30, 42, 56, 72, 18, 30, 44, 60, 78, 98, 120, 144, 34, 54, 76, 100]
答案 1 :(得分:1)
好的,我不太确定我是否理解你的问题,因为你谈到模数11,但似乎也使用2到9之间的数字。
但让我们首先将1..20作为一个列表开始,这可能如下:
list(range(1,21)) (This is if you want to include the 20)
接下来,要将某个整数转换为2到9之间的数字,您可以执行以下操作:
x -> x % 8 + 2
结合这两个,你可以列出一个列表:
[((x-1) % 8 + 2) * x for x in xrange(1,21)]
(添加-1以从2开始而不是从3开始第一个数字)
答案 2 :(得分:1)
如果您使用itertools.cycle
:
>>> itertools.cycle(range(2, 10))
2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5, ...
所以你可以简化你的功能,如下所示:
from itertools import cycle
def mod11(lst, max_weight=9):
multipliers = cycle(range(2, max_weight + 1))
zipped = zip(lst, multipliers))
summed = sum(a * b for a, b in zipped)
mod = 11 - (summed % 11)
return (0 if mod > 9 else mod)
答案 3 :(得分:1)
这里有很多好的答案,如果您想使用numpy
(通常对这类事情有好处),可以选择以下方法:
In [1]: import numpy as np
In [2]: a = np.arange(1, 21) # like range in numpy array
In [3]: a - 1 # calculation performs per element wise... so will a * n
Out[3]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
In [4]: a * ((a - 1) % 8 + 2) # directly translate the calculation
Out[4]:
array([ 2, 6, 12, 20, 30, 42, 56, 72, 18, 30, 44, 60, 78,
98, 120, 144, 34, 54, 76, 100])
答案 4 :(得分:1)
您可以使用itertools中的starmap和cycle。
首先创建一个要相乘的元组列表:
>>> from itertools import starmap, cycle
>>> li=zip(range(1,21), cycle(range(2,10)))
>>> li
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 2), (10, 3), (11, 4), (12, 5), (13, 6), (14, 7), (15, 8), (16, 9), (17, 2), (18, 3), (19, 4), (20, 5)]
然后使用starmap
和mul
(来自运算符)乘以:
>>> from operator import mul
>>> list(starmap(mul, li))
[2, 6, 12, 20, 30, 42, 56, 72, 18, 30, 44, 60, 78, 98, 120, 144, 34, 54, 76, 100]
如果你想直接理解,你可以这样做:
>>> [x*y for x, y in ((e+1, (e%8)+2) for e in range(20))]
[2, 6, 12, 20, 30, 42, 56, 72, 18, 30, 44, 60, 78, 98, 120, 144, 34, 54, 76, 100]
答案 5 :(得分:0)
也许oneliner:
s = map(lambda x : x*(x+1),list(range(1,20)))
基本上 map 是用于对表的每个元素进行相同操作的核心函数。第一个参数是将应用于每个元素的函数。如果你想记住生成另一个用于乘法的值,可以尝试一些生成器