Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 求两个相乘为20的整数。我能把这段代码写得更详细吗;蟒蛇的;?_Python_Python 3.x - Fatal编程技术网

Python 求两个相乘为20的整数。我能把这段代码写得更详细吗;蟒蛇的;?

Python 求两个相乘为20的整数。我能把这段代码写得更详细吗;蟒蛇的;?,python,python-3.x,Python,Python 3.x,我做了这段代码,在一个列表中找到两个整数(在本例中为[2,4,5,1,6,40,-1]),它们相乘到20。一开始我有点受困,但添加一个函数解决了我的问题。我向我的一个程序员朋友展示了这段代码,他说我可以让这段代码更“pythonic”,但我不知道怎么做 代码如下: num_list = [2,4,5,1,6,40,-1] def get_mult_num(given_list): for i in given_list: for j in range(i+1, len(

我做了这段代码,在一个列表中找到两个整数(在本例中为[2,4,5,1,6,40,-1]),它们相乘到20。一开始我有点受困,但添加一个函数解决了我的问题。我向我的一个程序员朋友展示了这段代码,他说我可以让这段代码更“pythonic”,但我不知道怎么做

代码如下:

num_list = [2,4,5,1,6,40,-1]

def get_mult_num(given_list):
    for i in given_list:
        for j in range(i+1, len(given_list)): #for j not to be == i and to be in the list
            mult_two_numbers = i * j
            if mult_two_numbers == 20:
                return i,j

print(get_mult_num(num_list)) 

[(i,j)对于num_列表中的i对于num_列表中的j如果i我可以考虑使用列表理解。如果给定列表中存在多个这样的对,这也有助于找到它们

num_list = [2,4,5,1,6,40,-1]

mult_num = [(num_list[i],num_list[j]) for i in range(len(num_list)) for j in range(i+1, len(num_list)) if num_list[i]*num_list[j] == 20]
print mult_num
输出:

[(4, 5)]

这是我对它的看法,它使用:


我想你的朋友可能在暗示当它使代码更干净时使用它(有时不会)。

我不一定认为它是“非Python的”,你在使用标准的Python习语循环你的数据并产生一个结果,或者
None

并非您生成了正确的实现。虽然
i
给定的\u数上循环,
j
在从
i+2
len(给定的\u数)的整数上循环
,将
给定列表中的值与索引混合?对于您的样本输入,您从半开放范围[4,7]、[6,7]、[7,7](空)、[3,7]、[8,7](空)、[42,7)(空)和[42,7](空)中获取
j
[1,7)。它产生正确答案完全是运气,而不是因为正确性;如果你给你的函数列表
[2,10]
,它找不到解决方案!您想再次循环给定的\u编号,受限于切片,或者从当前索引
i
开始生成索引,但是您的外部循环也需要添加一个
enumerate()
调用:

for ii, i in enumerate(given_numbers):
    for j in given_numbers[ii + 1:]:
        # ...

所有这些都远没有它所能做到的那么有效;Python标准库为您提供了生成
i,j
对的工具,而无需嵌套
for
循环或切片或其他形式的过滤

您的双循环应该生成整数输入,因此使用生成唯一的
i,j
对:

from itertools import combinations

def get_mult_num(given_list):
    return [(i, j) for i, j in combinations(given_list, 2) if i * j == 20]
这假设可以有零个或多个这样的解决方案,而不仅仅是一个解决方案

如果您只需要第一个结果或
None
,可以使用:

接下来,您可能不想产生所有可能的组合,而是想将问题颠倒过来。如果您将
给定的_列表
转换为一个集合,您可以轻松地检查目标数字20是否可以被任何给定的数字干净地无余数地除掉,并且除法的结果更大,并且也是数字集合中的整数.这会在线性时间内给你一个答案

您可以通过用小于目标值平方根的数字除以来进一步限制搜索,因为您在输入数字中找不到匹配的更大的值(给定一个数字
n
,它的平方根
s
,根据定义
s*(s+1)
将大于
n

如果我们向函数中添加目标编号的参数,并将其设为a,则会得到:

def gen_factors_for(target, numbers):
    possible_j = set(numbers)
    limit = abs(target) ** 0.5
    for i in numbers:
        if abs(i) < limit and target % i == 0:
            j = target // i
            if j in possible_j and abs(j) > abs(i):
                yield i, j
def gen_系数(目标、数字):
可能的_j=设置(数字)
极限=abs(目标)**0.5
以数字表示的i:
如果abs(i)<限制和目标%i==0:
j=目标//i
如果j在可能的_j和abs(j)>abs(i):
收益率i,j
这种方法比测试所有排列要快得多,特别是当您需要找到所有可能的因素时。请注意,我在这里创建了两个函数生成器,以平衡比较:

>>> import random, operator
>>> from timeit import Timer
>>> def gen_factors_for_division(target, numbers):
...     possible_j = set(numbers)
...     limit = abs(target) ** 0.5
...     for i in numbers:
...         if abs(i) < limit and target % i == 0:
...             j = target // i
...             if j in possible_j and abs(j) > abs(i):
...                 yield i, j
...
>>> def gen_factors_for_combinations(target, given_list):
...     return ((i, j) for i, j in combinations(given_list, 2) if i * j == target)
...
>>> numbers = [random.randint(-10000, 10000) for _ in range(100)]
>>> targets = [operator.mul(*random.sample(set(numbers), 2)) for _ in range(5)]
>>> targets += [t + random.randint(1, 100) for t in targets]  # add likely-to-be-unsolvable numbers
>>> for (label, t) in (('first match:', 'next({}, None)'), ('all matches:', 'list({})')):
...     print(label)
...     for f in (gen_factors_for_division, gen_factors_for_combinations):
...         test = t.format('f(t, n)')
...         timer = Timer(
...             f"[{test} for t in ts]",
...             'from __main__ import targets as ts, numbers as n, f')
...         count, total = timer.autorange()
...         print(f"{f.__name__:>30}: {total / count * 1000:8.3f}ms")
...
first match:
      gen_factors_for_division:    0.219ms
  gen_factors_for_combinations:    4.664ms
all matches:
      gen_factors_for_division:    0.259ms
  gen_factors_for_combinations:    3.326ms
>导入随机,运算符
>>>从timeit导入计时器
>>>def gen_部门的系数(目标、数字):
…可能的_j=设置(数字)
…极限=abs(目标)**0.5
…以数字表示的i:
…如果abs(i)<限制和目标%i==0:
…j=目标//i
…如果j在可能的情况下_j和abs(j)>abs(i):
…屈服i,j
...
>>>def gen_系数_用于_组合(目标,给定_列表):
…如果i*j==目标,则返回组合中i,j的(i,j)(给定的_列表,2)
...
>>>数字=[random.randint(-10000,10000)表示范围(100)]
>>>目标=[operator.mul(*random.sample(set(number),2))用于范围(5)]
>>>目标+=[t+random.randint(1100)表示目标中的t]#添加可能无法解决的数字
>>>对于(('first match:','next({},None'),('all matches:','list({}'))中的(标签,t):
…打印(标签)
…对于f in(第二代因子用于第二代划分,第二代因子用于第二代组合):
…test=t.format('f(t,n)'
…计时器=计时器(
…f“[{test}对于ts中的t]”,
…'从_umain__;导入目标为ts,数字为n,f')
…计数,总计=timer.autorange()
…打印(f“{f.\u name}>30}:{total/count*1000:8.3f}ms”)
...
第一场比赛:
分区的GENU系数:0.219ms
组合的发电机系数:4.664ms
所有匹配项:
分区的发电机系数:0.259ms
组合的发电机系数:3.326ms

请注意,我生成了10个不同的随机目标,以避免两种方法中出现幸运的最佳情况。

您可以通过使用itertools.combines(而不是嵌套循环)来查找所有的数字对,从而使其更具pythonic性。不总是这样,但经常在索引上迭代,如
中针对范围内的I(len(L)):
比直接在值上迭代要少一些pythonic,如L:
中的v:

Python还允许您通过
yield
关键字将函数生成生成器,这样,您就可以通过迭代函数调用获得每一对,而不是返回第一对乘以20的结果

import itertools

def factors(x, numbers):
    """ Generate all pairs in list of numbers that multiply to x.
    """
    for a, b in itertools.combinations(numbers, 2):
        if a * b == x:
            yield (a, b)

numbers = [2, 4, 5, 1, 6, 40, -1]
for pair in factors(20, numbers):
    print(pair)

我想到了这个。它稍微颠倒了方法,在
num\u列表中搜索所需的配对伙伴
def get_mult_num(given_list):
    multiplies_to_20 = (
        (i, j) for i, j in combinations(given_list, 2)
        if i * j == 20)
    return next(multiplies_to_20, None)
def gen_factors_for(target, numbers):
    possible_j = set(numbers)
    limit = abs(target) ** 0.5
    for i in numbers:
        if abs(i) < limit and target % i == 0:
            j = target // i
            if j in possible_j and abs(j) > abs(i):
                yield i, j
>>> import random, operator
>>> from timeit import Timer
>>> def gen_factors_for_division(target, numbers):
...     possible_j = set(numbers)
...     limit = abs(target) ** 0.5
...     for i in numbers:
...         if abs(i) < limit and target % i == 0:
...             j = target // i
...             if j in possible_j and abs(j) > abs(i):
...                 yield i, j
...
>>> def gen_factors_for_combinations(target, given_list):
...     return ((i, j) for i, j in combinations(given_list, 2) if i * j == target)
...
>>> numbers = [random.randint(-10000, 10000) for _ in range(100)]
>>> targets = [operator.mul(*random.sample(set(numbers), 2)) for _ in range(5)]
>>> targets += [t + random.randint(1, 100) for t in targets]  # add likely-to-be-unsolvable numbers
>>> for (label, t) in (('first match:', 'next({}, None)'), ('all matches:', 'list({})')):
...     print(label)
...     for f in (gen_factors_for_division, gen_factors_for_combinations):
...         test = t.format('f(t, n)')
...         timer = Timer(
...             f"[{test} for t in ts]",
...             'from __main__ import targets as ts, numbers as n, f')
...         count, total = timer.autorange()
...         print(f"{f.__name__:>30}: {total / count * 1000:8.3f}ms")
...
first match:
      gen_factors_for_division:    0.219ms
  gen_factors_for_combinations:    4.664ms
all matches:
      gen_factors_for_division:    0.259ms
  gen_factors_for_combinations:    3.326ms
import itertools

def factors(x, numbers):
    """ Generate all pairs in list of numbers that multiply to x.
    """
    for a, b in itertools.combinations(numbers, 2):
        if a * b == x:
            yield (a, b)

numbers = [2, 4, 5, 1, 6, 40, -1]
for pair in factors(20, numbers):
    print(pair)
for val in num_list:    
    if 20 / val in num_list:
        print(val, int(20/val))