在列表中查找属性等于某个值(满足任何条件)的对象

sel*_*ler 183 python django list

我有对象列表.我想在这个列表中找到一个(第一个或任何)对象,它具有等于的属性(或方法结果 - 无论如何)value.

找到它的最佳方法是什么?

这是测试用例:

  class Test:
      def __init__(self, value):
          self.value = value

  import random

  value = 5

  test_list = [Test(random.randint(0,100)) for x in range(1000)]

  # that I would do in Pascal, I don't believe isn't anywhere near 'Pythonic'
  for x in test_list:
      if x.value == value:
          print "i found it!"
          break
Run Code Online (Sandbox Code Playgroud)

我认为使用生成器并reduce()没有任何区别,因为它仍然会遍历列表.

ps:方程式value只是一个例子.当然我们想要得到满足任何条件的元素.

agf*_*agf 374

next((x for x in test_list if x.value == value), None)
Run Code Online (Sandbox Code Playgroud)

这将从列表中获取与条件匹配的第一个项目,None如果没有项目匹配则返回.这是我首选的单表达形式.

然而,

for x in test_list:
    if x.value == value:
        print "i found it!"
        break
Run Code Online (Sandbox Code Playgroud)

天真的循环中断版本,完美的Pythonic - 它简洁,清晰,高效.为了使它符合单线的行为:

for x in test_list:
    if x.value == value:
        print "i found it!"
        break
else:
    x = None
Run Code Online (Sandbox Code Playgroud)

如果您没有退出循环,这将分配Nonexbreak.

  • +1令人放心的"天真的循环中断版本,完全是Pythonic". (54认同)
  • @StewartDale你问的是什么并不完全清楚,但我认为你的意思是`......如果getattr(x,x.fieldMemberName)== value`.这将从`x`获取属性,其名称存储在`fieldMemberName`中,并将其与`value`进行比较. (3认同)
  • @ThatTechGuy -- `else` 子句应该在 `for` 循环中,而不是在 `if` 中。(拒绝编辑)。 (3认同)
  • @agf 哇,我真的不知道存在.. http://book.pythontips.com/en/latest/for_-_else.html 酷! (2认同)

Moh*_*ari 26

一个简单的例子:我们有以下数组

li = [{"id":1,"name":"ronaldo"},{"id":2,"name":"messi"}]
Run Code Online (Sandbox Code Playgroud)

现在,我们要在数组中找到 id 等于 1 的对象

  1. 使用next具有列表理解的方法
next(x for x in li if x["id"] == 1 )
Run Code Online (Sandbox Code Playgroud)
  1. 使用列表理解并返回第一项
[x for x in li if x["id"] == 1 ][0]
Run Code Online (Sandbox Code Playgroud)
  1. 自定义功能
def find(arr , id):
    for x in arr:
        if x["id"] == id:
            return x
find(li , 1)
Run Code Online (Sandbox Code Playgroud)

输出所有上述方法是 {'id': 1, 'name': 'ronaldo'}


Nim*_*avi 16

由于尚未提及完成.好过滤器过滤你的过滤元素.

功能编程ftw.

####### Set Up #######
class X:

    def __init__(self, val):
        self.val = val

elem = 5

my_unfiltered_list = [X(1), X(2), X(3), X(4), X(5), X(5), X(6)]

####### Set Up #######

### Filter one liner ### filter(lambda x: condition(x), some_list)
my_filter_iter = filter(lambda x: x.val == elem, my_unfiltered_list)
### Returns a flippin' iterator at least in Python 3.5 and that's what I'm on

print(next(my_filter_iter).val)
print(next(my_filter_iter).val)
print(next(my_filter_iter).val)

### [1, 2, 3, 4, 5, 5, 6] Will Return: ###
# 5
# 5
# Traceback (most recent call last):
#   File "C:\Users\mousavin\workspace\Scripts\test.py", line 22, in <module>
#     print(next(my_filter_iter).value)
# StopIteration


# You can do that None stuff or whatever at this point, if you don't like exceptions.
Run Code Online (Sandbox Code Playgroud)

我知道通常在python列表中,首选理解是首选,或者至少这是我读过的内容,但我不认为问题是诚实的.当然,Python不是FP语言,但Map/Reduce/Filter是完全可读的,是函数式编程中最标准的标准用例.

你去吧 了解你的功能编程.

过滤条件清单

它不会比这更容易:

next(filter(lambda x: x.val == value,  my_unfiltered_list)) # Optionally: next(..., None) or some other default value to prevent Exceptions
Run Code Online (Sandbox Code Playgroud)

  • @vrnvorona 我的评论是在 2018 年发表的 (3认同)
  • 1:我不知道Python 2。当我开始使用Python时,Python 3已经可用。不幸的是,我对 agf 指出的 Python 2.2.@freethebees 的具体情况一无所知。如果您不喜欢异常,您可以使用 next(..., None) 或其他一些默认值。我还将它作为注释添加到我的代码中。 (2认同)
  • @freethebees 你不应该在 2020 年 1 月 1 日之后使用 python 2,因为它已经停止支持了。 (2认同)