Python 简化“如果”条件
苏。。。我正在努力解决问题。8在欧拉项目现场 我想知道是否有一种更干净的方法来写这个if条件Python 简化“如果”条件,python,string,list,Python,String,List,苏。。。我正在努力解决问题。8在欧拉项目现场 我想知道是否有一种更干净的方法来写这个if条件 n="7316717653..." # there are 1000 digits (https://projecteuler.info/problem=8) Max=0 s=[int(s) for s in n] for i in range(len(s)-3): if s[i]*s[i+1]*s[i+2]*s[i+2] > Max: Max=s[i]*s[i+
n="7316717653..." # there are 1000 digits
(https://projecteuler.info/problem=8)
Max=0
s=[int(s) for s in n]
for i in range(len(s)-3):
if s[i]*s[i+1]*s[i+2]*s[i+2] > Max:
Max=s[i]*s[i+1]*s[i+2]*s[i+3]
print(Max)
# In particular
if s[i]*s[i+1]*s[i+2]*s[i+2] > Max:
Max=s[i]*s[i+1]*s[i+2]*s[i+3]
我怎样才能写得更好呢?我必须把它也写下来
如果s[i]*s[i+1]*s[i+2]*s[i+2]*s[i+3]…*s[i+13]
所以如果能找到更好的方法就好了。。
提前谢谢你
编辑:
我的帖子写得很差。。。对不起
我的意思是:
如果s[i]*s[i+1]*s[i+2]*s[i+3]*s[i+4]*s[i+5]*s[i+6]*s[i+7]*s[i+8]*s[i+9]*s[i+10]*s[i+11]*s[i+12]*s[i+13]>Max:
或者更好的建议,谢谢
Max=maxMax,s[i]*s[i+1]*s[i+2]*s[i+3]*s[i+4]*s[i+5]*s[i+6]*s[i+7]*s[i+8]*s[i+9]*s[i+10]*s[i+11]*s[i+12]*s[i+13]
以更好的方式?
就像用一种自动化的方式来做s[i+n]13或任何时间。
对不起,我的英语不好
编辑2:
我编辑的时候你们回答了,谢谢你们 只需直接使用max函数,无需if语句
Max = max(Max, s[i]*s[i+1]*s[i+2]*s[i+3])
对于累积产品,您可以求助于numpy这样的库,它已经矢量化了函数cumprod和prod。比如说,
import numpy as np
>>> np.cumprod([1,2,3,4,5])
array([ 1, 2, 6, 24, 120])
及
当然,替换s的虚拟[1,2,3,4,5],相应切片如s[:13]可用于计算乘积:
from functools import reduce
from operator import mul
reduce(mul, [2, 3, 4]) # calculates 2 * 3 * 4
# 24
您的代码将是,13位数字相乘,如问题末尾所述:
from functools import reduce
from operator import mul
n = "7316717653..." # there are 1000 digits
s = [int(s) for s in n]
maxi = max(reduce(mul, s[i:i+13]) for i in range(len(s)-13))
print(maxi)
编辑
虽然写起来很紧凑,但这并不是很有效,尤其是当相乘的数字序列的长度变长时
一个更有效的方法是在滑动窗口中将我们的产品视为由数字构成。当窗口向右移动一位数字时,乘积除以刚从左边出来的数字,再乘以右边输入的数字
这样,无论序列的长度如何,我们只需要得到两个数字,并在每个步骤上执行两个操作
def findmax(seq, k=13):
p = reduce(mul, seq[:k])
maxi = p
for i in range(k, len(seq)):
p = p * seq[i] // seq[i-k]
if p > maxi:
maxi = p
return maxi
一些粗略的计时显示,对于长度为2的序列,它已经快了2倍多,对于长度为13的序列,它快了5倍多。如果你问如何简化s[i]*s[i+1]*s[i+2]*s[i+2],你可以在列表切片的同时使用乘积函数。我从你那里得到了定义 但是,如果您正在寻找性能优化,那么这不是实现它的方法。这是On*m,其中m是相乘的子序列的长度,但您可以利用这样一个事实,即当您转到下一个切片时,您将当前乘积除以您要经过的元素,然后乘以您要添加的元素,以得到On算法
highest = product(s[0:4])
for i in range(len(s)-5):
highest = max(highest, highest/s[i]*s[i+4]))
print(highest)
哎呀,如果有任何0位数字,第二种方法就不起作用。处理这一问题将使其变得非常复杂。您正在寻找的if条件缩短器是functools.reduce和operator.mul以及字符串片段的组合:
m = functools.reduce(operator.mul, s[i:i+13])
if m > Max:
Max = m
不要忘记导入functools和operator,您可以使用python库解决这个问题。与列表或字符串相比,它处理数字数据的效率更高 例如,您可以使用以下方法解决此问题:
import numpy as np
#n = "7316717653..." # there are 1000 digits
n = '7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'
n_as_nparray = np.array([int(character) for character in n])
every_thirteen_char = np.array([n_as_nparray[i:i+13] for i in range(len(n)-13)])
您将拥有一个shape=987,13的数组
那么,您的最大产品将是:
并使用以下方法找到序列:
>>> every_thirteen_char[every_thirteen_char.prod(axis=1).argmax()]
array([5, 5, 7, 6, 6, 8, 9, 6, 6, 4, 8, 9, 5])
虽然没有@Thierry提供的简单解决方案那么漂亮,但这个解决方案的速度要快5倍左右。因为包含零使乘积为零,所以我拆分了这个字符上的文本。在使用reduce获得前13个字符的产品之后,我根据新数字与下降的数字的比率来更新这个产品。产品始终根据全球最大值进行测试
big_number = '7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'
n = 13
global_max = 0
for chunk in big_number.split('0'):
if len(chunk) < n:
continue
product = reduce(lambda x, y: x * int(y), chunk[:n], 1) # Product of first `n` integers in `chunk`.
global_max = max(global_max, product)
for i in range(n, len(chunk)):
product *= (int(chunk[i]) / int(chunk[i - n])) # Rolling product of window size `n`.
if product > global_max:
global_max = product
>>> int(global_max)
23514624000
也不要用Max作为变量名。是的,我已经更改了变量名。我几乎删除了我的答案,认为它与你的答案基本相似。但是,您的第二种方法不起作用,因为当s[i]为零时,您会得到一个零分错误。这给出了提示,但实际上并没有回答问题。@Alexander感谢否决票,但问题已经改变了很多次,我是第一张海报-很显然,它最初必须使用if语句aloneI抱歉,@Alexander,它给出了正确的答案。我只是通过将代码复制到python控制台python 3.5.2、numpy 1.17.2中进行了检查,它为我提供了23514624000的最大乘积。然后,我访问并输入了这个号码,我收到了以下信息:祝贺你,你对问题8的回答是正确的。确实如此。我道歉。我想我只是看了你的最终结果,它给出了顺序而不是解决方案。没问题。我明白了,更直观的是,最后的答案是在课文的结尾。刚刚制作和编辑来修复这个问题。谢谢。由于字符串中有零,您编辑的第二个方法无法工作。具体来说,p=p*seq[i]//seq[i-k]会导致零分错误。
>>> every_thirteen_char.prod(axis=1).max()
23514624000
>>> every_thirteen_char[every_thirteen_char.prod(axis=1).argmax()]
array([5, 5, 7, 6, 6, 8, 9, 6, 6, 4, 8, 9, 5])
big_number = '7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'
n = 13
global_max = 0
for chunk in big_number.split('0'):
if len(chunk) < n:
continue
product = reduce(lambda x, y: x * int(y), chunk[:n], 1) # Product of first `n` integers in `chunk`.
global_max = max(global_max, product)
for i in range(n, len(chunk)):
product *= (int(chunk[i]) / int(chunk[i - n])) # Rolling product of window size `n`.
if product > global_max:
global_max = product
>>> int(global_max)
23514624000
%%timeit -n 1000 # Code above.
# 437 µs ± 76.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit -n 1000
s = [int(s) for s in big_number]
maxi = max(reduce(mul, s[i:(i + 13)]) for i in range(len(s) - 13))
# 2.46 ms ± 916 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# Using numpy.
%%timeit -n 1000
n_as_nparray = np.array([int(character) for character in big_number])
every_thirteen_char = np.array([n_as_nparray[i:(i + 13)] for i in range(len(big_number) - 13)])
every_thirteen_char.prod(axis=1).max()
# 2.81 ms ± 418 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# Using pandas with a rolling window.
%%timeit -n 100
s = pd.Series([int(c) for c in big_number])
s.rolling(window=13, min_periods=1).apply(np.prod, raw=True).max().astype(int)
# 8.06 ms ± 830 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)