Python中的递归列表理解?

Python中的递归列表理解?,python,list-comprehension,Python,List Comprehension,可以在Python中定义递归列表理解吗 可能是一个简单的例子,但大致如下: nums = [1, 1, 2, 2, 3, 3, 4, 4] willThisWork = [x for x in nums if x not in self] # self being the current comprehension 这样做可能吗?不可能。它不起作用,在执行列表理解时没有可参考的self 当然,主要原因是列表理解不是为这种用途而设计的。不确定这是否是您想要的,但您可以编写嵌套列表理解: xs =

可以在Python中定义递归列表理解吗

可能是一个简单的例子,但大致如下:

nums = [1, 1, 2, 2, 3, 3, 4, 4]
willThisWork = [x for x in nums if x not in self] # self being the current comprehension

这样做可能吗?

不可能。它不起作用,在执行列表理解时没有可参考的
self


当然,主要原因是列表理解不是为这种用途而设计的。

不确定这是否是您想要的,但您可以编写嵌套列表理解:

xs = [[i for i in range(1,10) if i % j == 0] for j in range(2,5)]
assert xs == [[2, 4, 6, 8], [3, 6, 9], [4, 8]]
从您的代码示例中,您似乎只想消除重复项,这可以通过集合来实现:

xs = sorted(set([1, 1, 2, 2, 3, 3, 4, 4]))
assert xs == [1, 2, 3, 4]
不,没有(记录在案的、可靠的、稳定的,…;-)的方式来指代“当前的理解”。您可以使用一个循环:

res = []
for x in nums:
  if x not in res:
    res.append(x)
当然,这是非常昂贵的(O(N平方)),因此您可以使用辅助的
集合对其进行优化(我假设
res
中的项目顺序与
nums
中的项目顺序保持一致,否则
set(nums)
就可以了;-):

对于非常长的列表(O(N)而不是N的平方),这是非常快的

Edit:在Python 2.5或2.6中,
vars()[''.[1]]
实际上可能在
self
所需的角色中工作(对于非嵌套listcomp)。。。这就是为什么我对我的陈述进行了限定,澄清了没有记录的、可靠的、稳定的方式来访问“正在建立的列表”--那个奇特的、未记录的“名称”
“[1]”
(故意选择不是有效的标识符;-)是“实现工件”的顶点任何依赖它的代码都应该摆脱它的痛苦;-)

没有

但看起来您正试图列出NUM中的独特元素

您可以使用
集合

unique_items = set(nums)
请注意,NUM中的项需要是可散列的

您还可以执行以下操作。我已经接近你最初的想法了。但这并不像创建
集那样有效

unique_items = []
for i in nums:
    if i not in unique_items:
        unique_items.append(i)
这样做:

nums = [1, 1, 2, 2, 3, 3, 4, 4]
set_of_nums = set(nums)
unique_num_list = list(set_of_nums)
甚至这个:

unique_num_list = sorted(set_of_nums)

事实上你可以!这个例子有一个解释,希望能说明如何

定义recursive example以仅在数字为5或更多时获取该数字,如果不是,则增加该数字并再次调用“check”函数。重复此过程,直到达到5,此时返回5

print [ (lambda f,v: v >= 5 and v or f(f,v+1))(lambda g,i: i >= 5 and i or g(g,i+1),i) for i in [1,2,3,4,5,6] ]
结果:

[5, 5, 5, 5, 5, 6]
>>> 
基本上,这两个匿名函数以这种方式交互:

let f(g,x) = {  
                 expression, terminal condition
                 g(g,x), non-terminal condition
             }

let g(f,x) = {  
                 expression, terminal condition
                 f(f,x), non-terminal condition
             }
使g,f成为“相同”函数,除了在一个或两个函数中添加一个子句,其中修改了参数,以使达到终端条件,然后执行 f(g,x)通过这种方式,g变成了f的副本,使其类似于:

f(g,x) = {  
                 expression, terminal condition
                 {
                    expression, terminal condition,
                    g(g,x), non-terminal codition
                 }, non-terminal condition
             }
您需要这样做,因为在执行匿名函数时,您无法访问匿名函数本身

i、 e

在这个例子中,让A=第一个函数,B=第二个函数。我们把经过的B称为f,把i称为v。现在,由于B本质上是a的一个副本,它是一个已经传递的参数,你现在可以调用B,就像调用a一样

这将在列表中生成阶乘

print [ (lambda f,v: v == 0 and 1 or v*f(f,v-1))(lambda g,i: i == 0 and 1 or i*g(g,i-1),i) for i in [1,2,3,5,6,7] ]

[1, 2, 6, 120, 720, 5040]
>>> 

从Python 3.8开始,引入(
:=
运算符),可以命名表达式的结果,我们可以通过更新列表中的变量引用已经看到的项:

# items = [1, 1, 2, 2, 3, 3, 4, 4]
acc = []; [acc := acc + [x] for x in items if x not in acc]
# acc = [1, 2, 3, 4]
这:

  • 初始化列表
    acc
    ,该列表表示已看到的元素的运行列表
  • 对于每个项目,检查它是否已经是
    acc
    列表的一部分;若否:
    • 通过赋值表达式将项目追加到
      acc
      acc:=acc+[x]
    • 同时使用新的
      acc
      值作为该项的映射值

如果订单不是问题,
list(set(num))
。否则,请检查泄漏抽象警报中的
unique\u everseed
。在我看来,理解不应该被认为是循环,即使它们可能在cpython中被实现为循环。.集合操作使其成为O(n log(n)),我非常确定。@Python中的dash tom bang集合不是作为红黑树实现的(像在STL中),但据我所知,它将是O(n)@Justin是正确的——python集合和dict都是经过良好优化的散列,添加项的摊销成本为O(1),查找成本为O(1)。不需要对列表进行理解<代码>唯一数量列表=列表(数量集合)
sorted(set of nums)
返回一个列表。不需要克隆lambda;您可以使用通用代理作为第一个lambda,以允许任何类型的第二个lambda调用自身<代码>(lambda f,arg:f(f,arg))(lambda self,v:..,firstvalue)
非常整洁,将来肯定会用到
print [ (lambda f,v: v == 0 and 1 or v*f(f,v-1))(lambda g,i: i == 0 and 1 or i*g(g,i-1),i) for i in [1,2,3,5,6,7] ]

[1, 2, 6, 120, 720, 5040]
>>> 
# items = [1, 1, 2, 2, 3, 3, 4, 4]
acc = []; [acc := acc + [x] for x in items if x not in acc]
# acc = [1, 2, 3, 4]