[英]updating a variable inside an if condition within a list comprehension
i tried my best to write the following code in a list comprehension but ended up getting wrong我尽力在列表理解中编写以下代码,但最终出错了
for i in range(1,n+1):
L.append(i+(k*sin))
if(i % (k) == 0):
sin*=-1
return [i+(k*sin) if(i % (k*2) == 0) sin*=-1 for i in range(1,n+1)]
You can do this with a list comprehension, but you should take a different approach.您可以通过列表推导来做到这一点,但您应该采用不同的方法。
Let's say k == 3
: then your sequence will look like this:假设
k == 3
:那么您的序列将如下所示:
1 + k*sin
2 + k*sin
3 + k*sin
4 + -k*sin
5 + -k*sin
6 + -k*sin
7 + k*sin
8 + k*sin
9 + k*sin
...
Basically, you just want a list comprehension that looks like基本上,您只需要一个看起来像的列表理解
[i + n*sin for i, n in zip(range(1, n+1), ???)]
The question is, what do we replace ???
问题是,我们要替换什么
???
with to get our sequence of repeating k
and -k
values?来获得我们重复的
k
和-k
值的序列?
The itertools
module provides several tools for generating this: itertools
模块提供了几个工具来生成它:
repeat
- repeat a value some number of times repeat
- 重复一个值若干次chain
- concatenate two or more sequences into a single sequence chain
- 将两个或多个序列连接成一个序列cycle
- cycle through the values in a sequence repeatedly cycle
- 重复循环遍历序列中的值In this case, it's在这种情况下,它是
cycle(chain(repeat(k, k), repeat(-k, k)))
giving you给你
from itertools import repeat, chain, cycle
[i + n*sin for i, n in zip(range(1, n+1), cycle(chain(repeat(k, k), repeat(-k, k)))]
zip
ensures we only take a finite number of values from the infinite sequence. zip
确保我们只从无限序列中获取有限数量的值。
Another approach is to use another tool from itertool
, islice
, to take only the first n
values from the cycle.另一种方法是使用来自
itertool
的另一个工具islice
,仅从循环中获取前n
值。 Then we don't need range
anymore;然后我们不再需要
range
; we can use enumerate
to number those values from 1
to n
instead.我们可以使用
enumerate
将这些值从1
编号为n
。
from itertools import repeat, chain, cycle, islice
[i + n*sin for i, n in enumerate(islice(cycle(chain(repeat(k, k), repeat(-k, k))), n), start=1]
Both read better if you define ks
first:如果您先定义
ks
,则两者都读得更好:
ks = cycle(chain(repeat(k, k), repeat(-k, k)))
[i + n*sin for i, n in zip(range(1, n+1), ks)]
or或者
ks = cycle(chain(repeat(k, k), repeat(-k, k)))
[i + n*sin for i, n in enumerate(islice(ks, n), start=1)]
You can also optimize this a bit by repeating the value of k*sin
, rather than performing the multiplication for each element of the list.您还可以通过重复
k*sin
的值来优化这一点,而不是对列表的每个元素执行乘法。
ks = cycle(chain(repeat(k*sin, k), repeat(-k*sin, k)))
[i + n for i, n in ...] # using either zip or enumerate as before
What you want is to mathematically formulate your problem a little bit better, than it can easily be represented as a list comprehension.你想要的是在数学上更好地表达你的问题,而不是它可以很容易地表示为列表理解。
In essence, you want the a formula for the signal of sin
which is dependent on the index i
and on k
that will invert the signal every k
.本质上,您需要
sin
信号的公式,该公式取决于索引i
和k
,它将在每个k
反转信号。 That is represented by (-1) ** (i - 1) // k
.这由
(-1) ** (i - 1) // k
。
So, if you include that into your code, you should arrive at exactly what you want:因此,如果您将其包含到您的代码中,您应该得到您想要的:
return [i + (k * ((-1) ** ((i - 1) // k)) * sin) for i in range(1,n+1)]
Hope that helps!希望有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.