Python Lambda计数/循环函数

Rob*_*ood 5 python lambda

如果这是其他地方的问题,我很抱歉.通过谷歌和Stackforum搜索我没有找到任何可以推断出答案的内容; 但我觉得那部分就是我.

我正在尝试将lambdas作为一个概念,作为其中的一部分,我正在寻找使用它的方法.

所以,如果从功能的角度来看这是一个非常愚蠢的关于lambda的事情,请随时让我知道并解释.但无论哪种方式,我仍然想知道答案/仍然想知道如何用python语言做到这一点.

因此,出于测试目的,我有:

my_test = 'test_name'
testlist = ['test_name', 'test_name_dup', 'test_name_dup_1', 'test_name_dup_3']
Run Code Online (Sandbox Code Playgroud)

我正在寻找使用lambda创建一个循环的函数,并返回不在testlist中的第一个test_name_#.该功能最终将应用于文件名,但出于测试目的,我不得不远离实际读取文件名 - 给了我太多方法来搞砸了.

但my_test必须能够更改,测试列表将是文件路径列表.

所以,我正在寻找一个像以下的功能:

new_name = lambda x: my_test + '_' + str(x)
Run Code Online (Sandbox Code Playgroud)

但是初始值应该是x = 1,并且它应该继续,直到new_name不在testlist中.似乎:

bool(new_name not in testlist)
Run Code Online (Sandbox Code Playgroud)

可能是有用的东西.

但我无法想出一种方法将初始x设置为1,并使用(x + 1)循环直到bool为真.

我知道这是可能的,因为我发现一些CRAZY lambda示例循环遍历文件中的行.我只是无法理解它们(并且没有任何方式可以与它们一起玩,因为它们处理的是编程级别之外的事情.

在相关的说明中,我可以在此循环的开头添加值吗?(即我可以检查test_name,然后检查test_name_dup,然后检查test_name_dup_#)?

在此先感谢您的帮助!Lambdas(虽然非常酷)完全弄乱了我的脑袋.

Win*_*ert 6

Lambdas只是定义函数的另一种方式

def foo(x):
    return x + x
Run Code Online (Sandbox Code Playgroud)

是相同的

foo = lambda x: x + x
Run Code Online (Sandbox Code Playgroud)

所以让我们从一个功能开始,做你想要的

def first_missing(items, base):
    for number in itertools.count():
        text = base + '_' + str(number)
        if text not in items:
             return text
Run Code Online (Sandbox Code Playgroud)

首先要注意的是你不能在lambda中使用循环.所以我们需要在没有循环的情况下重写它.相反,我们将使用递归

def first_missing(items, base, number = 0):
        text = base + '_' + str(number)
        if text not in items:
             return text
        else:
             return first_missing(items, base, number + 1)
Run Code Online (Sandbox Code Playgroud)

现在,我们也不能在lambda中使用if/else块.但我们可以使用三元表达式

def first_missing(items, base, number = 0):
        text = base + '_' + str(number)
        return text if text not in items else first_missing(items, base, number + 1)
Run Code Online (Sandbox Code Playgroud)

我们不能在lambda中有局部变量,所以我们将使用技巧,默认参数

def first_missing(items, base, number = 0):
        def inner(text = base + '_' + str(number)):
            return text if text not in items else first_missing(items, base, number + 1)
        return inner()
Run Code Online (Sandbox Code Playgroud)

在这一点上,我们可以将内部重写为lambda

def first_missing(items, base, number = 0):
        inner = lambda text = base + '_' + str(number): text if text not in items else first_missing(items, base, number + 1)
        return inner()
Run Code Online (Sandbox Code Playgroud)

我们可以组合两行来摆脱内部局部变量

def first_missing(items, base, number = 0):
    return (lambda text = base + '_' + str(number): text if text not in items else first_missing(items, base, number + 1))()
Run Code Online (Sandbox Code Playgroud)

最后,我们可以把整个事情变成一个lambda

first_missing = lambda: items, base, number = 0: (lambda text = base + '_' + str(number): text if text not in items else first_missing(items, base, number + 1))()
Run Code Online (Sandbox Code Playgroud)

希望能让您深入了解自己能做些什么.但不是每个人都这样做.你可以告诉lambdas真的很难读.


Ósc*_*pez 2

lambda在这种情况下不需要使用 a ,一个简单的for循环就可以了:

my_test  = 'test_name_dup'  
testlist = ['test_name', 'test_name_dup','test_name_dup_1', 'test_name_dup_3']

for i in xrange(1, len(testlist)):
    if my_test + '_' + str(i) not in testlist:
        break

print my_test + '_' + str(i)
> test_name_dup_2
Run Code Online (Sandbox Code Playgroud)

如果你真的真的想使用 alambda来解决这个问题,你还必须学习 itertools、迭代器、过滤器等。我将在 thg435 的答案的基础上,以更惯用的方式编写它并解释它:

import itertools as it

iterator = it.dropwhile(
    lambda n: '{0}_{1}'.format(my_test, n) in testlist,
    it.count(1))

print my_test + '_' + str(iterator.next())
> test_name_dup_2
Run Code Online (Sandbox Code Playgroud)

理解上述解决方案的关键在于流程dropwhile()。它需要两个参数:一个谓词和一个可迭代对象,并返回一个迭代器,只要谓词为真,该迭代器就会从可迭代对象中删除元素;之后,返回每个元素。

对于可迭代对象,我传递了count(1)一个迭代器,它生成从 开始的无限数量的整数1

然后dropwhile()开始消耗整数,直到谓词为假;这是传递内联定义函数的好机会 - 这是我们的lambda. 它依次接收每个生成的整数,检查字符串 test_name_dup_# 是否存在于列表中。

当谓词返回false,dropwhile()返回时,我们可以通过调用它来检索使其停止的值next()