Python 带for循环的列表理解

Python 带for循环的列表理解,python,python-3.x,list-comprehension,Python,Python 3.x,List Comprehension,如何使用列表理解将列表中的前n个奇数加倍 以下是我的解决方案: >>> n = 2 >>> lst = [1, 2, 3, 4, 5, 6] >>> lst = [num for num in lst if num % 2 == 1] + [num for num in lst if num % 2 == 0] >>> lst = [num * 2 for num in lst[:n]] + lst[n:] >>

如何使用列表理解将列表中的前n个奇数加倍

以下是我的解决方案:

>>> n = 2
>>> lst = [1, 2, 3, 4, 5, 6]
>>> lst = [num for num in lst if num % 2 == 1] + [num for num in lst if num % 2 == 0]
>>> lst = [num * 2 for num in lst[:n]] + lst[n:]
>>> print(lst)
[2, 6, 5, 2, 4, 6]
您可以看到,我不能再保持相同的
lst
顺序了

更多示例:

n = 2
lst = [2, 2, 2, 2, 1, 2, 3]
output: lst = [2, 2, 2, 2, 2, 2, 6]
这个怎么样

n = 2
lst = [1, 2, 3, 4, 5, 6]

for i in range(n):
   lst[i]= lst[i]*2
这个怎么样

n = 2
lst = [1, 2, 3, 4, 5, 6]

for i in range(n):
   lst[i]= lst[i]*2

使用三元运算符

lst = [1, 2, 3, 4, 5, 6]
lst = [x * 2 if x % 2 == 1 and i <= n else x for i, x in enumerate(lst)]
更新:在先加倍
n
奇数整数的新要求下:

lst = [1, 2, 3, 4, 5, 6]

class Doubler:
    def __init__(self, n):
        self.n = n
    def proc(self, x):
        if self.n > 0 and x % 2:
            self.n -= 1
            return 2 * x
        return x

# Double first 2 odd elements
d = Doubler(n=2)
res = [d.proc(x) for x in lst]
print(res)
# [2, 2, 6, 4, 5, 6]

使用三元运算符

lst = [1, 2, 3, 4, 5, 6]
lst = [x * 2 if x % 2 == 1 and i <= n else x for i, x in enumerate(lst)]
更新:在先加倍
n
奇数整数的新要求下:

lst = [1, 2, 3, 4, 5, 6]

class Doubler:
    def __init__(self, n):
        self.n = n
    def proc(self, x):
        if self.n > 0 and x % 2:
            self.n -= 1
            return 2 * x
        return x

# Double first 2 odd elements
d = Doubler(n=2)
res = [d.proc(x) for x in lst]
print(res)
# [2, 2, 6, 4, 5, 6]

[num if num%2 else 2*num for num in list]。num if a if b else c将在b为真时返回a,否则返回c.

[num if num%2 else 2*num for num in list]。num if a if b else如果b为真,c将返回a,否则c.

原始要求的解决方案*“如果是奇数,则将列表中的第一个
n
数字加倍”: 由于您不想从原始列表中删除任何项目,因此不能使用列表理解语法的过滤器(for的
后面的
if
)。因此,您需要做的只是将要放入目标列表中的项目进行转换

对于索引
i
处的元素
x
,您的逻辑是这样的:

def transform(x, i, n):
    if i < n:
        if x % 2 == 1:
            return x * 2
    return x
当然,您也可以将其内联到列表中:

>>> n = 2
>>> lst = [1, 2, 3, 4, 5, 6]
>>> [transform(x, i, n) for i, x in enumerate(lst)]
[2, 2, 3, 4, 5, 6]
>>> [x * 2 if i < n and x % 2 == 1 else x for i, x in enumerate(lst)]
[2, 2, 3, 4, 5, 6]
原始要求的解决方案*“如果列表中的第一个
n
数字是奇数,则将其加倍”: 由于您不想从原始列表中删除任何项目,因此不能使用列表理解语法的过滤器(for
后面的
if
)。因此,您需要做的只是将要放入目标列表中的项目进行转换

对于索引
i
处的元素
x
,您的逻辑是这样的:

def transform(x, i, n):
    if i < n:
        if x % 2 == 1:
            return x * 2
    return x
当然,您也可以将其内联到列表中:

>>> n = 2
>>> lst = [1, 2, 3, 4, 5, 6]
>>> [transform(x, i, n) for i, x in enumerate(lst)]
[2, 2, 3, 4, 5, 6]
>>> [x * 2 if i < n and x % 2 == 1 else x for i, x in enumerate(lst)]
[2, 2, 3, 4, 5, 6]

用特定的名称命名事物,逻辑就会暴露出来

如何使用列表理解将列表中的前n个奇数加倍

我们有奇数:
v表示l中的v,如果n%2
。这是一个过滤器。 我们可以使用。我们称之为切片,其他语言可能称之为“take”。将它们加倍是一个每项操作,所以是一个映射。加入这些行动,我们将为您的问题找到一个答案:

[v*2 for v in islice((v for v in l if n%2), n)]
然而,这不是你想要的。问题是特殊性;你的问题没有说明如何处理第一个
n
奇数项之外的其他项,所以我忽略了它们

那么,如果我们想要复制您问题中未提及的所有项目,我们该怎么办?这意味着我们有三组:早期赔率、晚期赔率和偶数,所有这些都经过了明确的处理。后者可能被任意混合在一起,而我们知道晚赔率在早赔率之后。如您所示,将它们拆分为单独的流是不切实际的,因为这样并不能保持它们的相对顺序

我将应用更多的itertools函数来解决这个问题

from itertools import repeat, chain
oddfactors = chain(repeat(2, n), repeat(1))
outlist = [v*next(oddfactors) if v%2 else v
           for v in inlist]
请注意,迭代器
oddfactors
是为每个奇数项而不是偶数项读取的,因为if-else表达式在未使用时不会对表达式求值。迭代器已被使用,您需要创建另一个迭代器来再次执行该工作

可以将
oddfactors
迭代器的创建(以及整个范围)放在列表理解中,但我能想到的第一种方法是难以置信的丑陋:

from itertools import repeat, chain
outlist = [v*next(oddfactors) if v%2 else v
           for v,oddfactors in zip(
            inlist, 
            repeat(chain(repeat(2, n), repeat(1)))
           )]
这里的技巧是确保我们只创建一次链式迭代器,然后将其输入到每个映射操作中。这个练习对可读性和性能毫无帮助。使用嵌套理解将使它更简洁,但仍然只有一个迭代器,因此这是一种误导性的攻击

outlist = [v*next(oddfactors) if v%2 else v
           for oddfactors in [chain(repeat(2, n), repeat(1))]
           for v in inlist]

用特定的名称命名事物,逻辑就会暴露出来

如何使用列表理解将列表中的前n个奇数加倍

我们有奇数:
v表示l中的v,如果n%2
。这是一个过滤器。 我们可以使用。我们称之为切片,其他语言可能称之为“take”。将它们加倍是一个每项操作,所以是一个映射。加入这些行动,我们将为您的问题找到一个答案:

[v*2 for v in islice((v for v in l if n%2), n)]
然而,这不是你想要的。问题是特殊性;你的问题没有说明如何处理第一个
n
奇数项之外的其他项,所以我忽略了它们

那么,如果我们想要复制您问题中未提及的所有项目,我们该怎么办?这意味着我们有三组:早期赔率、晚期赔率和偶数,所有这些都经过了明确的处理。后者可能被任意混合在一起,而我们知道晚赔率在早赔率之后。如您所示,将它们拆分为单独的流是不切实际的,因为这样并不能保持它们的相对顺序

我将应用更多的itertools函数来解决这个问题

from itertools import repeat, chain
oddfactors = chain(repeat(2, n), repeat(1))
outlist = [v*next(oddfactors) if v%2 else v
           for v in inlist]
请注意,迭代器
oddfactors
是为每个奇数项而不是偶数项读取的,因为if-else表达式在未使用时不会对表达式求值。迭代器已被使用,您需要创建另一个迭代器来再次执行该工作

可以将
oddfactors
迭代器的创建(以及整个范围)放在列表理解中,但我能想到的第一种方法是难以置信的丑陋:

from itertools import repeat, chain
outlist = [v*next(oddfactors) if v%2 else v
           for v,oddfactors in zip(
            inlist, 
            repeat(chain(repeat(2, n), repeat(1)))
           )]
这里的技巧是确保我们只创建一次链式迭代器,然后将其输入到每个映射操作中。这个练习对可读性和性能毫无帮助。使用嵌套理解将使它更简洁,但仍然只有一个迭代器,因此这是一种误导性的攻击

outlist = [v*next(oddfactors) if v%2 else v
           for oddfactors in [chain(repeat(2, n), repeat(1))]
           for v in inlist]

为了让它起作用,你需要记下你已经看到的奇数。例如,您可以实例化
itertools.count
生成器,并在每次遇到奇数时使其前进:

from itertools import count
def f(l, n):
    odd = count()
    return [x * 2 if x % 2 and next(odd) < n else x for x in l]

要使其工作,您需要计算奇数