按数字范围乘以数字列表

时间:2016-09-05 19:46:51

标签: python

我正在尝试为模数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

6 个答案:

答案 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中的starmapcycle

首先创建一个要相乘的元组列表:

>>> 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)]

然后使用starmapmul(来自运算符)乘以:

>>> 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 是用于对表的每个元素进行相同操作的核心函数。第一个参数是将应用于每个元素的函数。如果你想记住生成另一个用于乘法的值,可以尝试一些生成器