如何使用列表推导式 return 第一项而不是整个列表?

How to return the first item rather than the entire list, using list comprehension?

我正在解决一个问题,我必须在列表中找到一个唯一的整数,使用 list.count(x) 很容易解决这个问题。但是,我无法将代码压缩成一行。

def find_uniq(arr):
    return [x for x in arr if arr.count(x) == 1]

我的代码工作正常,但它 returns 例如:[2] 而不是 2,或 [0.55] 而不是 0.55

有没有办法使用列表推导来 return 整数而不是包含整数的列表?

如果您确定您只想return传递列表中的一个整数您可以将return更改为

def find_uniq(arr):
    return [x for x in arr if arr.count(x) == 1][0]

但它只会 return 列表中唯一的第一个元素。如果你想return更多,列表是更好的方法

Return 使用索引。

def find_uniq(arr):
    return [x for x in arr if arr.count(x) == 1][0]

不是生成列表列表理解,而是创建一个生成器,从中获取第一个元素:

return next(x for x in arr if arr.count(x) == 1)

这引发了一个 StopIteration 列表中没有元素满足条件;你可以 return 像这样的默认值 None 像这样:

return next((x for x in arr if arr.count(x) == 1), None)

count一次又一次地迭代数组是否明智也值得怀疑;根据它的大小,这可能是非常低效的。先建个计数器可能效率更高:

from collections import Counter
return next(v for v, c in Counter(arr).items() if c == 1)

您已经有了列表理解的答案 -- 这是一种资源浪费。 不过,您的方法是有效的,因为它使用了 everyday/beginner 结构。在同一个论点中,我想提出两点建议:

  • 避免对 count();
  • 的冗余调用
  • 避免创建列表(因为一次只需要一个元素)。

假设我们有以下数组arr:

> arr = [random.randint(0,9) for _ in range(10)]
> arr
[6, 7, 0, 9, 3, 3, 3, 9, 8, 8]

对于第一点,可以创建一个set来减少计数:

> numbers_set = set(arr)
> numbers_set
{0, 3, 6, 7, 8, 9}

那你可以在我们朋友的帮助下拥有一台发电机filter:

> unique_numbers = filter(lambda x:arr.count(x)==1, numbers_set)
> print(next(unique_numbers))
0
> print(next(unique_numbers))
6
> print(next(unique_numbers))
7
> print(next(unique_numbers))
StopIteration: